Reputation: 1230
I am trying to do something very simple. Animate padding first then animate width.
@state var animate = false
Rect().frame(width: animate ? 200 : 1, height: 2).animate(Animation.easeOut(duration: 0.5).delay(0.5)).padding(.bottom, animate ? 300 : 10).animate(.easeOut)
From this code I expect the padding to be using the outermost animation modifier and the frame using the inner one. So I expect padding to animate first then frame to animate with a delay but they both are animating with the outermost animation.
What am I dont wrong?
Update: Working solution with Asperi's method of async after
@State private var width: CGFloat = 0.1
@State private var isFirstResponder = false
private var becameFirstResponder: Binding<Bool> { Binding (
get: { self.isFirstResponder },
set: {
self.isFirstResponder = $0
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.width = self.isFirstResponder ? 240 : 0.1
}
}
)}
var body: some View {
Divider().frame(width: width, height: 2)
.animation(Animation.easeOut(duration: 1), value: width)
.background(Color.primary)
.padding(.bottom, keyboard.height).animate(.easeOut)
}
As you can see this code is too complex for a very simple chained animation. Anyone got a solution without using asyncAfter?
Upvotes: 1
Views: 1014
Reputation: 258443
You delay animation but change both values at once, that's why it is confused.
Here is possible solution
struct DemoDelayedAnimations: View {
@State private var animate = false
// separate animatable values
@State private var width: CGFloat = 1
@State private var padding: CGFloat = 10
var body: some View {
VStack {
Rectangle()
.frame(width: width, height: 2)
.animation(.easeOut, value: width) // explicit to width
.padding(.bottom, padding)
.animation(.easeOut, value: padding) // explicit to padding
Divider()
Button("Go") {
self.padding = self.padding == 10 ? 300 : 10
// delay value change, not animation (it reacts on change)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.width = self.width == 1 ? 200 : 1
}
}
}
}
}
Upvotes: 1