SwiftUI:如何在取消计时器后重新启动计时器? [英] SwiftUI: How do you restart a timer after cancelling it?

查看:126
本文介绍了SwiftUI:如何在取消计时器后重新启动计时器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由主 ContentView TimerView 组成的导航视图.当我调用 self.timer.upstream.connect().cancel().

I have a navigation view consisting of the main ContentView and a TimerView. The TimerView has a timer which correctly increments and also correctly stops when I call self.timer.upstream.connect().cancel().

但是,当我返回ContentView然后再次导航到TimerView时,我希望计时器重新开始计数,但是这不会发生. secondsElapsed 确实重置为0,但计时器不运行.

However when I go back to ContentView and then navigate to TimerView again, I want the timer to start counting again however this does not happen. secondsElapsed does reset to 0 but the timer doesn't run.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: TimerView()) {
                Text("Go to Timer View")
            }
        }
    }
}

struct TimerView: View {
    @State var secondsElapsed = 0
    var timer = Timer.publish (every: 1, on: .main, in: .common).autoconnect()
    var body: some View {
        VStack {
            Text("\(self.secondsElapsed) seconds elapsed")
            Button("Stop timer",
                   action: {
                    self.timer.upstream.connect().cancel()
            })
        }.onReceive(timer) { _ in
            self.secondsElapsed += 1
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

推荐答案

据我所知(以及历史记录),在取消或无效后无法重新启动Timer.

To my knowledge (and historically), Timer cannot be restarted after cancellation or invalidation.

我要做的就是重新声明计时器.

What I do is just re-declare the timer.

以下是添加了一些个人喜好的示例:

Here is an example with some added personal preferences:

struct TimerView: View {
    @State var secondsElapsed = 0
    @State var timer: Timer.TimerPublisher = Timer.publish (every: 1, on: .main, in: .common)
    var body: some View {
        VStack {
            Text("\(self.secondsElapsed) seconds elapsed")
            Button("Stop timer",
                   action: {
                    self.cancelTimer() // Just to be a little more DRY/maintenance-friendly, but personal preference.
            })
        }.onAppear(perform: {
            self.instantiateTimer() // You could also consider an optional self.timer variable.
            self.timer.connect() // This allows you to manually connect where you want with greater efficiency, if you don't always want to autostart.
        }).onDisappear(perform: {
            // I don't know your exact flow, but you said you want the timer to restart upon return navigation.  
            // So, I am just assuming you want to stop the timer when you navigate out.  
            // But, you can also easily remove this closure.
            // Also, this may not run as you would intuit.
            self.cancelTimer()
        }).onReceive(timer) { _ in
            self.secondsElapsed += 1
        }
    }

    func instantiateTimer() {
        self.timer = Timer.publish (every: 1, on: .main, in: .common)
        return
    }

    func cancelTimer() {
        self.timer.connect().cancel()
        return
    }
}

这篇关于SwiftUI:如何在取消计时器后重新启动计时器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆