将计时器传递给 SwiftUI 中的子视图
Posted
技术标签:
【中文标题】将计时器传递给 SwiftUI 中的子视图【英文标题】:Passing a timer to a child view in SwiftUI 【发布时间】:2020-06-09 05:44:25 【问题描述】:在我的***视图中,我已经声明了一个像这样的计时器:
Struct ContentView: View
@State var timer = Timer.publish(every: 1, on: .main, in:
.common).autoconnect()
var body: some View
ZStack
if self.timerMode == .warmup
WarmupView(
timer: $timer
)
if self.timerMode == .work
WorkView(
timer: $timer
)
在子视图中,我希望能够访问和更新此计时器,它将作为唯一的事实来源。
Struct WarmupView: View
@Binding var timer: Publishers.Autoconnect<Timer.TimerPublisher>
@Binding var timeRemaining: Int
var body: some View
VStack
Text("\(self.timeRemaining)").font(.system(size: 160))
.onReceive(self.timer) _ in
if self.timeRemaining > 0
self.timeRemaining -= 1
计时器发布到预热视图没有问题,但是当 timerMode 更新为 .work(其代码几乎相同)并且视图发生更改时,计时器停止发布。
【问题讨论】:
不清楚整个工作流程。能否提供完整的演示代码? 【参考方案1】:只需将WarmupView
中的@Binding var timer
类型更改为Publishers.Autoconnect<Timer.TimerPublisher>
。 .autoconnect()
将计时器发布者包装在另一个发布者中,这会更改类型。
这是您的代码的简化版本:
struct ContentView: View
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State var remaining = 100
var body: some View
Text("\(remaining)")
.font(.system(size: 160))
.onReceive(timer) _ in
if self.remaining > 0
self.remaining -= 1
【讨论】:
我试过了,编译器阻塞了“使用未声明的类型'Publishers'” 您要导入 Combine 吗? 我导入了combine,现在定时器已成功通过。但是,当视图更改为传递相同计时器实例的另一个视图时,计时器将停止触发。如何让计时器在视图中保持不变? “视图变为另一个视图”是什么意思? 我刚刚更新了我的帖子以更清楚地解释。以上是关于将计时器传递给 SwiftUI 中的子视图的主要内容,如果未能解决你的问题,请参考以下文章
如何在 onReceive 计时器关闭 SwiftUI iOS 中导航另一个视图