The fifth version of the SwiftUI framework introduces many new APIs related to ScrollView, making it more powerful than before. This week begins a series of articles introducing the new features of ScrollView in SwiftUI. First we will discuss scroll transitions.
New scrollTransition
view modifiers allow watching views transition as the user scrolls through content. Allows us to know whether the view is in the ScrollView’s viewport and allows us to apply visual effects such as scaling, rotation, etc. Let’s look at an example.
struct ContentView: View {
var body: some View {
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)
}
}
}
}
}
As shown in the example above, use the new scrollTransition
view modifier to accept a closure with two parameters. The first parameter is a view without any effect, and the second parameter is ScrollTransitionPhase
an instance of type.
ScrollTransitionPhase
The type defines the state of view transitions in the ScrollView’s viewport. ScrollTransitionPhase
The type is an enumeration with three states: topLeading
, bottomTrailing
and identity
. ScrollTransitionPhase
The enumeration provides isIdentity
properties that allow us to check whether the view has completed the transition.
Typically, views are displayed during the identification phase without any effect. The SwiftUI framework animates all changes to your app during transitions. In the example, opacity
the view modifier is used to change the transparency of the view during the transition.
ScrollTransitionPhase
The enumeration also provides another property called value. The value range is -1 to 1, defining the numerical phase of the transition, where -1 represents topLeading
and 1 represents bottomTrailing
. You can take advantage of visual effects such as scaling when the view transitions from topLeading to bottomTrailing.
struct ContentView: View {
var body: some View {
ScrollView {
ForEach(0..<10, id: \.self) { _ in
Rectangle()
.fill(Color.random)
.frame(width: 300, height: 300)
.scrollTransition { view, transition in
view.scaleEffect(transition.isIdentity ? 1 : transition.value)
}
}
}
}
}
As shown in the example above, we use ScrollTransitionPhase
the value attribute of type to scale the view between transition stages.
scrollTransition
View modifiers allow adjusting the animation to be used during interpolated transitions.
struct ContentView: View {
var body: some View {
ScrollView {
ForEach(0..<10, id: \.self) { _ in
Rectangle()
.fill(Color.random)
.frame(width: 300, height: 300)
.scrollTransition(.animated(.bouncy)) { view, transition in
view.scaleEffect(transition.isIdentity ? 1 : transition.value)
}
}
}
}
}
Here, elastic animation is used to interpolate between transition stages. There are several options available to configure the transition: interactive
(Interactive), animated
(Use specific animation provided), and identity
(Disable animation).
struct ContentView: View {
var body: some View {
ScrollView {
ForEach(0..<10, id: \.self) { _ in
Rectangle()
.fill(Color.random)
.frame(width: 300, height: 300)
.scrollTransition(
topLeading: .identity,
bottomTrailing: .interactive
) { view, transition in
view.rotationEffect(.radians(transition.value))
}
}
}
}
}
It is also possible to use different configurations for topLeading
and transitions. bottomTrailing
In this example, use the identity configuration to disable the transition effect in that direction.