I have been trying to accomplish two main goals that I'm having a headache with. Sorry if it's a simple fix, I am a still bit new to swift/swiftui
@State
to change value based on how much time has passed.I've searched through Stack Overflow and found answers suggesting to use a timer:
struct CurrentDateView : View { @State var now = Date() let timer = Timer.publish(every: 1, on: .current, in: .common).autoconnect() var body: some View { Text("\(now)") .onReceive(timer) { self.now = Date() } } }
But how would I incorporate this so that something like @State
can be used change my value to false
after 7.5 seconds has passed:
@State randomTF : Bool = true
Or a Text("Please Enter Above")
to change to Text("Sorry Too Late")
after 7.5 seconds has passed
Although there's no direct, built-in way to run a Swift Task with a certain amount of delay, we can achieve that behavior by telling the task to sleep for a given number of nanoseconds before we actually start performing its operation: Task { // Delay the task by 1 second: try await Task.
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.
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 } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With