如何在 swiftUI 中 x 秒后触发操作

Ant*_*ney 19 xcode timer swift swiftui

我一直在努力实现两个令我头疼的主要目标。对不起,如果这是一个简单的修复,我对 swift/swiftui 还是有点陌生

  1. 经过一定时间后触发动作。
  2. @State根据经过的时间触发改变值。

我搜索了 Stack Overflow 并找到了建议使用计时器的答案:

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()
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我将如何合并它以便@State可以使用类似的东西false在 7.5 秒过去后将我的值更改为:

@State randomTF : Bool = true
Run Code Online (Sandbox Code Playgroud)

或 7.5 秒后Text("Please Enter Above")更改为 Text("Sorry Too Late")

Geo*_*e_E 35

创建一个延迟,然后将@State属性设置hasTimeElapsed为true时间过去后更新视图主体。

使用 Swift 5.5 和新的并发更新 ( async& await),您现在可以使用task(_:)如下内容:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅此答案Task.sleep(_:)中有关的更多信息。


旧版本

对于以下:

  • iOS 15.0+
  • macOS 12.0+
  • Mac 催化剂 15.0+
  • 电视操作系统 15.0+
  • watchOS 8.0+
  • Xcode 13.0+

您可以用来DispatchQueue延迟某些事情。触发它onAppear(perform:)(当视图第一次出现时发生)。如果需要,您也可以将延迟连接到按钮。

例子:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这感觉不像是这样做的预期方法......特别是因为 SwiftUI 视图是短暂的,并且可以随时销毁和重新初始化。我希望他们会在这里打算联合出版商 (2认同)

Rah*_*sal 14

// 添加1秒的延迟

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
   // your function
}
Run Code Online (Sandbox Code Playgroud)


esi*_*ver 6

.delay内置于 Swift 动画中。我实现了在视图出现后 0.5 秒启动动画的目标,代码如下:

 .onAppear(perform: {
    withAnimation(Animation.spring().delay(0.5)) {
         self.scale = 1.0
    }
 })
Run Code Online (Sandbox Code Playgroud)


Hlu*_*ung 6

从约翰的回答来看,这task是在视图出现之前执行的。来自苹果的文档:

添加要在此视图出现之前执行的异步任务。

所以这并不是真正的“onAppear”,而且我认为,如果延迟很短,它有可能在视图出现之前执行。这可能是意想不到的。

我建议继续使用.onAppear并只保留Task内部。无需声明任何扩展函数。像这样:

    .onAppear {
      Task { @MainActor in
        try await Task.sleep(for: .seconds(0.1))
        // your code here
      }
    }
Run Code Online (Sandbox Code Playgroud)