首页 > 解决方案 > 使用 Swift Combine 创建一个 Timer Publisher

问题描述

我一直在观看Data Flow Through SwiftUI WWDC talk。他们有一张带有示例代码的幻灯片,其中他们使用连接到 SwiftUI 视图的 Timer 发布者,并随时间更新 UI。

我正在处理一些我想做完全相同的事情的代码,但无法弄清楚这PodcastPlayer.currentTimePublisher是如何实现的,然后连接到 UI 结构。我也看过所有关于Combine 的视频。

我怎样才能做到这一点?

示例代码:

struct PlayerView : View {
  let episode: Episode
  @State private var isPlaying: Bool = true
  @State private var currentTime: TimeInterval = 0.0

  var body: some View {
    VStack { // ...
      Text("\(playhead, formatter: currentTimeFormatter)")
    }
    .onReceive(PodcastPlayer.currentTimePublisher) { newCurrentTime in
      self.currentTime = newCurrentTime
    }
  }
}

标签: swiftswiftuipublishercombine

解决方案


这里有一个组合计时器的示例。我使用的是全局变量,但当然您应该使用适用于您的场景的任何内容(环境对象、状态等)。

import SwiftUI
import Combine

class MyTimer {
    let currentTimePublisher = Timer.TimerPublisher(interval: 1.0, runLoop: .main, mode: .default)
    let cancellable: AnyCancellable?

    init() {
        self.cancellable = currentTimePublisher.connect() as? AnyCancellable
    }

    deinit {
        self.cancellable?.cancel()
    }
}

let timer = MyTimer()

struct Clock : View {
  @State private var currentTime: Date = Date()

  var body: some View {
    VStack {
      Text("\(currentTime)")
    }
    .onReceive(timer.currentTimePublisher) { newCurrentTime in
      self.currentTime = newCurrentTime
    }
  }
}

推荐阅读