在所有教程和官方文档中,我只看到当视图加载时计时器的初始化.

@State private var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

后来

.onReceive(timer) {....}

但是,我应该如何仅在单击按钮时初始化计时器,并将其分配给未分配/未连接的计时器.

稍后我需要取消并重新连接,但这不是这里的问题.这里的问题是只有在点击按钮后才能连接.

我试着这样开始

@State private var timer: Cancellable?

....

timer = Timer.publish(every: 1, on: .main, in: .common).connect()

但我不能像这样在计时器初始化时调用onReceive,因为首先:

Protocol 'Cancellable' as a type cannot conform to 'Publisher'

第二个

Argument type 'Cancellable?' does not conform to expected type 'Cancellable'

推荐答案

只需将计时器放在子视图中,并用bool控制其可见性.当移除TimerView时,状态被 destruct ,计时器停止.

struct ContentView: View {
    @State var started = false

    var body: some View {
        VStack {
            Button(started ? "Stop" : "Start") {
                started.toggle()
            }
            if started {
                TimerView()
            }
        }
    }
}

struct TimerView: View {

    @State private var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    ...

Swift相关问答推荐

变量捕获:变量在函数闭包中的行为

在`NavigationStack`中使用`SafeAreaInset`修饰符时出现SwiftUI异常行为

从后台线程获取@发布属性的值(不更改它)是正确的吗?

编写Swift字符串的属性包装时遇到问题

如何使泡泡上的箭头直达封闭矩形

如何在SWIFT Memory中处理对VAR数组的更新(对COW感到困惑)

在Swift中,将秒设置为0也等于将1添加到分钟

Swift图表';chartXVisibleDomain挂起或崩溃

如何通过 Enum 属性使用新的 #Predicate 宏获取

当将新值推送到 NavigationStack 时,SwiftUI 的 navigationDestination 已在堆栈的早期声明

当字符串包含 \r\n 时,NSRegularExpression 不起作用

Swift Property Wrappers-Initialization 失败并显示无法将‘Double’类型的值转换为预期的参数类型

NavigationStack 和 TabView - 工具栏和标题不显示

在 struct 中的序列和非序列泛型函数之间进行 Select

如何使用 ISO 国家代码(2 个字母)查找区域设置标识符

Swift UI 不重绘 NSViewRepresentable 包装的文本字段

组合 flatMap 不会返回预期的上下文结果类型

使用 swift 运行 pod install 时出错

为什么'nil' 与 Swift 3 中的 'UnsafePointer' 不兼容?

Objective-C 方法与可选需求方法 Swift 冲突