问题
In the following Playground example, the UI updates with the current date correctly, however when navigating away from the page and coming back the timer does not resume ticking:
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())
How do I have the timer start updating again when the page starts showing?
I have seen solutions that involve wrapping the Timer in another class, but nothing that can be done in the View.
I thought calling in connect()
in onAppear {}
would do it.
回答1:
Reinitializing your timer and date inside the onAppear would work:
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")
}
}
}
}
回答2:
Timer is canceled when there is no more subscribers, and when timer is cancelled it cannot be started again... so you need to make either not cancelling timer or recreate timer every time first tab is selected.
Here is possible solution (case 1, tested with 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 !!
}
}
来源:https://stackoverflow.com/questions/60888539/how-do-i-resume-a-published-timer-in-swiftui-after-navigating-to-a-different-pag