导航到其他页面后,如何在SwiftUI中恢复已发布的计时器



在下面的Playground示例中,UI会正确更新当前日期,但当导航离开页面并返回时,计时器不会继续计时:

import SwiftUI
import PlaygroundSupport
struct MainTabView: View {
let timer = Timer.publish(every: 1, on: .main, in: .common)
@State var time = Date()
var body: some View {
TabView {
VStack {
Text("(time)").onReceive(self.timer) { self.time = $0 }
}
.onAppear { _ = self.timer.connect() }
.tabItem {
Text("Page 1")
}
Text("Page 2").tabItem {
Text("Page 2")
}
Text("Page 3").tabItem {
Text("Page 3")
}
}
}
}
PlaygroundPage.current.setLiveView(MainTabView())

当页面开始显示时,如何让计时器再次开始更新?

我看到了一些解决方案,包括将Timer封装在另一个类中,但在View中无法执行任何操作。

我以为在onAppear {}中调用connect()就可以了

在onAppear中重新初始化计时器和日期将起作用:

struct ContentView: View {
@State private var timer = Timer.publish(every: 1, on: .main, in: .common)
@State var time = Date()
var body: some View {
TabView {
VStack {
Text("(time)").onReceive(self.timer) { self.time = $0 }
}
.onAppear(perform: {
self.time = Date()
self.timer = Timer.publish(every: 1, on: .main, in: .common)
_ = self.timer.connect()
})
.tabItem {
Text("Page 1")
}
Text("Page 2").tabItem {
Text("Page 2")
}
Text("Page 3").tabItem {
Text("Page 3")
}
}
}
}

当没有更多订阅者时,计时器将被取消,当计时器被取消时,它将无法再次启动。。。因此,您需要在每次选择第一个选项卡时不取消计时器或重新创建计时器。

以下是可能的解决方案(案例1,用Xcode 11.4测试(

struct MainTabView: View {
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State var time = Date()
var body: some View {
TabView {
VStack {
Text("(time)")
}
.tabItem {
Text("Page 1")
}
Text("Page 2").tabItem {
Text("Page 2")
}
Text("Page 3").tabItem {
Text("Page 3")
}
}.onReceive(self.timer) { self.time = $0 } // here !!
}
}

最新更新