将计时器传递给 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&lt;Timer.TimerPublisher&gt;.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 中导航另一个视图

来自 @Published 属性的 SwiftUI 动画从视图外部更改

Swiftui NavigationView 计时器延迟

如何将通用视图传递给 SwiftUI 中的结构

将多个子视图传递给 SwiftUI 中的视图

SwiftUI - 如何制作启动/停止计时器