Reputation: 53
I would like to scale some view with animation and go back to the original scale. The way I figured out to do it is by using DispatchQueue.main.asyncAfter
with deadline matching the end of scale up animation. As shown in following code. My question is if there is better way to do that (more SwiftUI way, or just simpler).
import SwiftUI
struct ExampleView: View {
@State private var isPulse = false
var body: some View {
VStack {
Text("Hello")
.scaleEffect(isPulse ? 3 : 1)
ZStack {
Capsule()
.frame(width: 100, height: 40)
.foregroundColor(.pink)
Text("Press me")
}
.onTapGesture {
let animationDuration = 0.4
withAnimation(.easeInOut(duration: animationDuration)) {
isPulse.toggle()
}
DispatchQueue.main.asyncAfter(deadline: .now() + animationDuration) {
withAnimation(.easeInOut) {
isPulse.toggle()
}
}
}
}
}
}
struct ExampleView_Previews: PreviewProvider {
static var previews: some View {
ExampleView()
}
}
Upvotes: 3
Views: 709
Reputation: 154631
You can use two withAnimation
statements with the second one that scales the text down using a .delay(animationDuration)
:
.onTapGesture {
let animationDuration = 0.4
withAnimation(.easeInOut(duration: animationDuration)) {
isPulse.toggle()
}
withAnimation(.easeInOut(duration: animationDuration).delay(animationDuration)) {
isPulse.toggle()
}
}
You could also replace the two calls to withAnimation
with a for loop
:
.onTapGesture {
let animationDuration = 0.4
for delay in [0, animationDuration] {
withAnimation(.easeInOut(duration: animationDuration).delay(delay)) {
isPulse.toggle()
}
}
}
Upvotes: 3