How it works
ScrollTargetBehaviorProperties is the structure that SwiftUI hands to a scroll target behavior so it can declare how it wants to participate in scrolling. Rather than configuring a behavior with scattered modifiers, the properties value carries a behavior's preferences — such as whether the behavior intends to take over scroll deceleration — in one place that the scroll system reads when it composes its final motion. Reach for it when you write a custom type conforming to ScrollTargetBehavior and need to advertise that behavior's characteristics to the surrounding scroll view.
Conform a type to ScrollTargetBehavior
ScrollTargetBehaviorProperties exists to describe a behavior, so you first need a behavior to describe. A custom type that adopts the ScrollTargetBehavior protocol becomes the unit the scroll view consults, like
SnapBehaviorin the example, which conforms toScrollTargetBehavior.Resolve each target in updateTarget(_:context:)
The protocol's core requirement is where the behavior does its work, computing where scrolling should come to rest. Here
updateTarget(_ target: inout ScrollTarget, context: TargetContext)readstarget.rect.origin.yand rewrites it, snapping the resting offset to the nearest multiple ofheight.Expose preferences through ScrollTargetBehaviorProperties
Alongside updateTarget, a behavior can surface a ScrollTargetBehaviorProperties value to tell the scroll system how it behaves at a higher level — for instance, declaring its relationship to the scroll view's deceleration.
SnapBehaviorrelies on the default properties, which is why it only needs to override the resolution logic inupdateTarget.Attach the behavior with scrollTargetBehavior(_:)
A behavior, and the properties it reports, only take effect once installed on a scroll container. The
.scrollTargetBehavior(SnapBehavior())modifier on theScrollViewis what wires the behavior — and thus its ScrollTargetBehaviorProperties — into the live scroll system.
let height: CGFloat = 60 in updateTarget to a larger value like 120 and watch each gesture settle on coarser, more widely spaced resting positions.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct ScrollTargetBehaviorPropertiesDemo: View {
var body: some View {
ScrollView {
VStack(spacing: 16) {
ForEach(1..<13) { i in
Text("Item \(i)")
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue.opacity(0.15))
.cornerRadius(8)
}
}
.padding()
}
.scrollTargetBehavior(SnapBehavior())
}
}
struct SnapBehavior: ScrollTargetBehavior {
func updateTarget(_ target: inout ScrollTarget, context: TargetContext) {
let height: CGFloat = 60
target.rect.origin.y = (target.rect.origin.y / height).rounded() * height
}
}