SwiftUI Transitions: Opacity, Slide, Move, Scale, Asymmetric, Custom
Basics of SwiftUI transitions
In SwiftUI you can add effects when a view is inserted or removed from the hierarchy. This is known as transitions.
In the following sections, we’ll see a few basic types of transitions in action. Let’s get started.
Opacity Transition
SwiftUI already provides an opacity
modifier out of the box. But did you know you could fade in and out views using the transition modifier as well? Here’s how to use opacity to transition a view across both the states:
.transition(.opacity)
Based on the Button
tap, SwiftUI inserts and removes the RoundedRectangle
— thereby giving a transition effect.
Scale Transition
Like the scaleEffect
animation, a scale
transition lets us grow and shrink view size:
.transition(.scale)
Here’s how to use the above transition in action:
RoundedRectangle(cornerRadius: 20)
.fill(Color.orange)
.frame(width: 100, height: 100)
.transition(.scale)
With no scale values, the view shrinks and vanishes. However, you can customize the scale parameter in the following way:
.transition(.scale(scale: 0.5))
Moreover, you can also customize the position from which the transition begins with the anchorPoint
parameter:
.transition(.scale(anchor: UnitPoint(x: 1, y: 0)))
Here’s an example output of the scale transition in action:
Few inferences we can draw from the above transition:
UnitPoint(x: 1, y: 0) -- transitions towards top right
UnitPoint(x: -1, y: 0) -- transitions towards top leftUnitPoint(x: 0, y: 1) -- transitions towards bottom left
UnitPoint(x: 0, y: -1) -- transitions towards bottom right
Slide Transition
A slide transition is used to move views from left to right:
.transition(.slide)
Move Transition
While the slide transition only works in one direction, you can use the move
transition to make it work in other directions too:
.transition(.move(edge: .leading)).transition(.move(edge: .trailing)).transition(.move(edge: .top)).transition(.move(edge: .bottom))
For a more specific control over the position of views, you can use the offset
transition as shown below:
.transition(.offset(x: 10, y: 10))
Asymmetric Transition
An asymmetric
transition lets you specify different transitions for insertion and removal of views. Like a move transition for adding the view and an opacity transition for removing it.
Here’s a sample asymmetric
transition that scales on insertion and moves the view to the right on removal:
Combining Transitions
You can even combine multiple transitions to create a unique effect. Here are a few examples:
.transition(.slide.combined(with: .scale)).transition(.move(edge: .trailing).combined(with: .move(edge: .top)))
The following transition combines two move transitions: trailing and top — to bring a diagonal transition effect:
RoundedRectangle(cornerRadius: 20)
.fill(Color.blue)
.frame(width: 100, height: 100)
.transition(.move(edge: .trailing).combined(with: .move(edge: .top)))
Creating Customised Transitions
We can also build custom transition modifiers by extending AnyTransition
.
For instance, here’s an example to create a slideAndScale
transition:
extension AnyTransition {static var scaleAndSlide: AnyTransition {
AnyTransition.scale.combined(with: .slide)
}
}
There are so many more powerful transitions you can build with MatchedGeometryEffect
. We’ll explore it in another tutorial.
That’s all for now. Thanks for reading.