scrollTransition, new in iOS 17, applies visual effects to a view as it enters and leaves the
ScrollView viewport: fade, scale, rotate, anything a modifier can do. SwiftUI animates the
change for you.
The Transition Closure
The closure receives the plain view and a ScrollTransitionPhase. Render the identity phase
untouched and apply effects in the other phases.
ScrollView {
ForEach(0..<10, id: \.self) { _ in
Rectangle()
.fill(Color.random)
.frame(width: 300, height: 300)
.scrollTransition { view, transition in
view.opacity(transition.isIdentity ? 1 : 0.3)
}
}
}
ScrollTransitionPhase is an enum with three cases: topLeading, identity, and
bottomTrailing. isIdentity is the quick check for "fully inside the viewport".
Scaling the Effect with the Phase Value
The phase's value property runs from -1 (topLeading) through 0 (identity) to 1
(bottomTrailing), so effects can interpolate instead of switching.
.scrollTransition { view, transition in
view.scaleEffect(transition.isIdentity ? 1 : transition.value)
}
Configuring the Animation
Pass a configuration ahead of the closure: .interactive tracks the scroll, .animated(_:)
runs a chosen animation, and .identity disables the effect.
.scrollTransition(.animated(.bouncy)) { view, transition in
view.scaleEffect(transition.isIdentity ? 1 : transition.value)
}
The two edges can differ, for example no effect while entering at the top but an interactive one while leaving at the bottom.
.scrollTransition(
topLeading: .identity,
bottomTrailing: .interactive
) { view, transition in
view.rotationEffect(.radians(transition.value))
}