How to trigger action after x seconds in swiftUI
.delay
is built-in to Swift animations. I achieved my goal of launching an animation 0.5 seconds after a view appeared with the following code:
.onAppear(perform: {
withAnimation(Animation.spring().delay(0.5)) {
self.scale = 1.0
}
})
Create a delay, which then sets the @State
property hasTimeElapsed
to true
when the time has elapsed, updating the view body.
With Swift 5.5 and the new concurrency updates (async
& await
), you can now use task(_:)
like the following:
struct ContentView: View {
@State private var hasTimeElapsed = false
var body: some View {
Text(hasTimeElapsed ? "Sorry, too late." : "Please enter above.")
.task(delayText)
}
private func delayText() async {
// Delay of 7.5 seconds (1 second = 1_000_000_000 nanoseconds)
try? await Task.sleep(nanoseconds: 7_500_000_000)
hasTimeElapsed = true
}
}
See more info about Task.sleep(nanoseconds:)
in this answer.
Older versions
Xcode 13.0+ now supports concurrency, backwards compatible! However, here is still the 'old' way to do it:
You can use DispatchQueue
to delay something. Trigger it with onAppear(perform:)
(which happens when the view first appears). You could also hook the delay up to a Button instead if wanted.
Example:
struct ContentView: View {
@State private var hasTimeElapsed = false
var body: some View {
Text(hasTimeElapsed ? "Sorry, too late." : "Please enter above.")
.onAppear(perform: delayText)
}
private func delayText() {
// Delay of 7.5 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 7.5) {
hasTimeElapsed = true
}
}
}