I want to make a view appear, do something, then disappear with DispatchQueue
. I want to toggle the showHand
to show the hand then toggleHandAnimation
to make the hand move left and right. After some time e.g. 5 seconds, I want that hand to disappear.
I have an implementation below which seems to be working on the build but it seems like there would be a better way. I have the code below.
What is the guidance on implementing views where you want to run multiple tasks at different points in time async?
import SwiftUI
struct ContentView: View {
@State var toggleHandAnimation: Bool = false
@State var showHand: Bool = true
var body: some View {
if showHand {
Image(systemName: "hand.draw")
.font(Font.system(size: 100))
.offset(x: toggleHandAnimation ? -40 : 0, y: 0)
.animation(Animation.easeInOut(duration: 0.6).repeatCount(5))
.onAppear {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() 1, execute: {
toggleHandAnimation.toggle()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() 5, execute: {
showHand.toggle()
})
})
}
}
}
}
CodePudding user response:
I think this is what you are looking for:
struct ContentView: View {
@State var toggleHandAnimation: Bool = false
@State var showHand: Bool = true
var body: some View {
ZStack {
Color(uiColor: .systemBackground)
if showHand {
Image(systemName: "hand.draw")
.font(Font.system(size: 100))
.offset(x: toggleHandAnimation ? -40 : 0, y: 0)
.onAppear {
withAnimation(Animation.easeInOut(duration: 0.5).repeatCount(10)) {
toggleHandAnimation.toggle()
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() 5, execute: {
showHand.toggle()
})
}
}
}
}
}
A few things, you should read up on intrinsic vs. extrinsic animations. You were trying to use an intrinsic one, but for a situation like this, it should be extrinsic(i.e., withAnimation()
. Also, .animation(_ animation:)
has been deprecated because it does not work well. You should be using .animation(_ animation:, value:)
.
Also, I aligned the time so that the animation ends and the hand disappears. The nice thing with using the withAnimation()
is that you can animate multiple things occur with the same animation.
As you can see, you din't need to nest theDispatchQueues
. You only needed the one to make the view disappear.
Lastly, I put this all in a ZStack and set a color on that, so that there was always a view to return. The reason is, this will crash if there is suddenly no view being returned. That is what would happen at the end of the animation with out the color. Obviously, you can have whatever view you want, that was just an example.