SwiftUI Transforms and Animations
Want more? Subscribers can view all 471 episodes. New episodes are released regularly.
Creating Card View
To build a wallet UI, we will start by creating a card view using a VStack
. We want to use the same view multiple times so we will extract the contents into a new view typed called CardView
. We can extract the title and color into properties so they can be passed in.
struct ContentView : View {
@State var expanded: Bool = false
var body: some View {
ZStack {
CardView(title: "Walmart", color: .blue)
.offset(x: 0, y: expanded ? -400 : -40)
.scaleEffect(expanded ? 1 : 0.90)
CardView(title: "Target", color: .red)
.offset(x: 0, y: expanded ? -200 : -20)
.scaleEffect(expanded ? 1 : 0.95)
CardView(title: " Card", color: .black)
.tapAction {
self.expanded.toggle()
}
}
.offset(x: 0, y: expanded ? 150 : 0)
.animation(.spring(mass: 1.0, stiffness: 100, damping: 20, initialVelocity: 0))
}
}
struct CardView : View {
let title: String
let color: Color
var body: some View {
ZStack {
Rectangle()
.fill(color)
.cornerRadius(10)
.frame(width: 320, height: 210)
Text(title)
.font(.largeTitle)
.bold()
.foregroundColor(.white)
}.shadow(radius: 6)
}
}
To make the cards collapse on top of each other we will change the view to ZStack
.
Adding Transforms
Currently the cards are all on top of each other so you can only see the top card. We can utilize transforms to nudge the cards up and give them a smaller size to give a sense of depth.
To move the cards slightly up we will set the .offset
to the cards placed below the top card. We will also reduce the card size with .scaleEffect
.
@State var expanded: Bool = false
var body: some View {
ZStack {
CardView(title: "Walmart", color: .blue)
.offset(x: 0, y: -40)
.scaleEffect(0.90)
CardView(title: "Target", color: .red)
.offset(x: 0, y: -20)
.scaleEffect(0.95)
CardView(title: " Card", color: .black)
}
.offset(x: 0, y: 0)
}
Adding Declarative Animation
To see the card expanding once clicked on them we will first create a boolean @State
property wrapper to indicate the state of the view (expanded or not). Next we create a .tapAction
on the top card. This will help us to toggle the boolean variable.
Next we use this variable to inspect the expanded state in and choose a value for .offset
and .scaleEffect
. Now we will add a fun animation using .animation
with a .spring
animation style.
We can tweak the spring
parameters to give a more realistic looking animation and control how bouncy it feels.
@State var expanded: Bool = false
var body: some View {
ZStack {
CardView(title: "Walmart", color: .blue)
.offset(x: 0, y: expanded ? -400 : -40)
.scaleEffect(expanded ? 1 : 0.90)
CardView(title: "Target", color: .red)
.offset(x: 0, y: expanded ? -200 : -20)
.scaleEffect(expanded ? 1 : 0.95)
CardView(title: " Card", color: .black)
.tapAction {
self.expanded.toggle()
}
}
.offset(x: 0, y: expanded ? 150 : 0)
.animation(.spring(mass: 1.0, stiffness: 100, damping: 20, initialVelocity: 0))
}