简体   繁体   中英

How to trigger action after x seconds in swiftUI

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

  1. trigger an action after a certain time has elapsed.
  2. trigger an @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

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 usetask(_:) 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)
        await Task.sleep(7_500_000_000)
        hasTimeElapsed = true
    }
}

See more info about Task.sleep(_:) in this answer .


Older versions

For below:

  • iOS 15.0+
  • macOS 12.0+
  • Mac Catalyst 15.0+
  • tvOS 15.0+
  • watchOS 8.0+
  • Xcode 13.0+

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
        }
    }
}

.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
    }
 })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM