eiv*_*dml 9 publisher swift swiftui combine
我一直在看通过SwiftUI WWDC进行的数据流。他们有一张带有示例代码的幻灯片,其中他们使用Timer发布者,该发布者连接到SwiftUI视图,并随时间更新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
}
}
}
Run Code Online (Sandbox Code Playgroud)
kon*_*iki 16
这里有一个合并计时器的例子。我使用的是全局变量,但是您当然应该使用适用于您的方案的任何变量(environmentObject,State等)。
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
Moj*_*ini 11
ObservableObject
以创建使用斯威夫特结合了定时器出版商
class TimeCounter: ObservableObject {
@Published var time = 0
lazy var timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in self.time += 1 }
init() { timer.fire() }
}
Run Code Online (Sandbox Code Playgroud)
就是这样!现在你只需要观察变化:
struct ContentView: View {
@StateObject var timeCounter = TimeCounter()
var body: some View {
Text("\(timeCounter.time)")
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我实现了一个带有新功能的组合计时器,允许您在不同的时间间隔之间切换。
class CombineTimer {
private let intervalSubject: CurrentValueSubject<TimeInterval, Never>
var interval: TimeInterval {
get {
intervalSubject.value
}
set {
intervalSubject.send(newValue)
}
}
var publisher: AnyPublisher<Date, Never> {
intervalSubject
.map {
Timer.TimerPublisher(interval: $0, runLoop: .main, mode: .default).autoconnect()
}
.switchToLatest()
.eraseToAnyPublisher()
}
init(interval: TimeInterval = 1.0) {
intervalSubject = CurrentValueSubject<TimeInterval, Never>(interval)
}
}
Run Code Online (Sandbox Code Playgroud)
要启动计时器,只需订阅该publisher
属性。
SomeView()
.onReceive(combineTimer.publisher) { date in
// ...
}
Run Code Online (Sandbox Code Playgroud)
您可以通过更改属性切换到具有不同间隔的新计时器interval
。
combineTimer.interval = someNewInterval
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1355 次 |
最近记录: |