👔TimerView (scheduledTimer)
Combine ⟩ Timer ⟩ TimerView (scheduledTimer)
// 2022.03.25: (*) use Timer.scheduledTimer()
import SwiftUI
import Combine
/// 👔 TimerView (Timer.scheduledTimer)
/// ```
/// TimerView { ... }
/// TimerView(every: 2) { ... }
/// TimerView(every: 3, update: { timer in ... }) { ... }
/// ```
struct TimerView<Content: View>: View {
// ⭐️ # of seconds between firings of timer
let interval: TimeInterval
// ⭐️ timer event handler
let update: (Timer) -> Void
// ⭐️ generate timer content
@ViewBuilder var content: () -> Content
// init
init(
every interval: TimeInterval = 1,
update: @escaping (Timer) -> Void = {_ in}, // default: do nothing
@ViewBuilder content: @escaping () -> Content
) {
self.interval = interval
self.content = content
self.update = update
}
// ⭐️ detect whether app has gone background
@Environment(\.scenePhase) private var scenePhase
@State private var isActive = true
var body: some View {
content()
.onAppear {
// ⭐️ scheduled timer
Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { timer in
// ⭐️ if app goes background, stop updating immediately.
guard isActive else { return }
update(timer)
}
}
// ⭐️ mark the app inactive once it goes background.
.onChange(of: scenePhase) { newPhase in
isActive = (newPhase == .active)
}
}
}
Last updated
Was this helpful?