I have a problem with animation in SwiftUI, if I'm using .animation
, my animation is not working.
ZStack(alignment: .bottom) {
VStack {
Button("Button") {
showView.toggle()
}
Spacer()
}
if showView {
RoundedRectangle(cornerRadius: 30)
.frame(height: UIScreen.main.bounds.height * 0.5)
.transition(.move(edge: .bottom))
.animation(.easeInOut, value: showView)
}
}
.ignoresSafeArea(edges: .bottom)
But if I'm using withAnimation
in my button's action closure, and delete .animation
or keep it, it is working.
ZStack(alignment: .bottom) {
VStack {
Button("Button") {
withAnimation {
showView.toggle()
}
}
Spacer()
}
if showView {
RoundedRectangle(cornerRadius: 30)
.frame(height: UIScreen.main.bounds.height * 0.5)
.transition(.move(edge: .bottom))
.animation(.easeInOut, value: showView)
}
}
.ignoresSafeArea(edges: .bottom)
Can someone explain me how this works ? I'm trying with DispatchQueue.main.async
, it's still the same.
You're defining 2 different states:
RoundedRectangle
if showView = trueRoundedRectangle
if showView = falseSo, every time showView
changes, the body
will be re-rendered. If it toggles from false -> true, then RoundedRectangle
will be displayed instantly without any animations because it's not here until showView = true
. And if it toggles from true -> false, then it can be dismissed with animation because now, it's a part of the View. You may try this to make it show/disappear more smoothly:
ZStack(alignment: .bottom) {
VStack {
Button("Button") {
showView.toggle()
}
Spacer()
}
RoundedRectangle(cornerRadius: 30)
.frame(height: showView ? (UIScreen.main.bounds.height * 0.5) : 0)
.transition(.move(edge: .bottom))
.animation(.easeInOut, value: showView)
}
.ignoresSafeArea(edges: .bottom)