SwiftUI - 如何制作启动/停止计时器
Posted
技术标签:
【中文标题】SwiftUI - 如何制作启动/停止计时器【英文标题】:SwiftUI - How to Make A Start/Stop Timer 【发布时间】:2020-08-23 14:58:32 【问题描述】:我的目标是在 SwiftUI 中创建一个从 0 开始的视图。当您按下视图时,计时器应该开始向上计数,再次点击会停止计时器。最后,当您再次点击启动计时器时,计时器应从 0 开始。
这是我当前的代码:
import SwiftUI
struct TimerView: View
@State var isTimerRunning = false
@State private var endTime = Date()
@State private var startTime = Date()
let timer = Timer.publish(every: 0.001, on: .main, in: .common).autoconnect()
var tap: some Gesture
TapGesture(count: 1)
.onEnded(
isTimerRunning.toggle()
)
var body: some View
Text("\(endTime.timeIntervalSince1970 - startTime.timeIntervalSince1970)")
.font(.largeTitle)
.gesture(tap)
.onReceive(timer) input in
startTime = isTimerRunning ? startTime : Date()
endTime = isTimerRunning ? input : endTime
此代码使计时器立即启动并且永不停止,即使我点击它也是如此。计时器也会向后(变为负数)而不是向前。
有人可以帮我理解我做错了什么吗?另外,我想知道这对于计时器来说是否是一个好的整体策略(使用 Timer.publish)。
谢谢!
【问题讨论】:
【参考方案1】:这是一个固定版本。看看我所做的更改。
如果计时器正在运行,.onReceive
现在会更新 timerString
。 timeString 是现在(即Date()
)和startTime
之间的间隔。
如果定时器没有运行,点击定时器会设置startTime
。
struct TimerView: View
@State var isTimerRunning = false
@State private var startTime = Date()
@State private var timerString = "0.00"
let timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()
var body: some View
Text(self.timerString)
.font(Font.system(.largeTitle, design: .monospaced))
.onReceive(timer) _ in
if self.isTimerRunning
timerString = String(format: "%.2f", (Date().timeIntervalSince( self.startTime)))
.onTapGesture
if !isTimerRunning
timerString = "0.00"
startTime = Date()
isTimerRunning.toggle()
上述版本虽然简单,但让我感到困扰的是Timer
一直在发布。我们只需要在计时器运行时发布Timer
。
这是一个启动和停止Timer
的版本:
struct TimerView: View
@State var isTimerRunning = false
@State private var startTime = Date()
@State private var timerString = "0.00"
@State private var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View
Text(self.timerString)
.font(Font.system(.largeTitle, design: .monospaced))
.onReceive(timer) _ in
if self.isTimerRunning
timerString = String(format: "%.2f", (Date().timeIntervalSince( self.startTime)))
.onTapGesture
if isTimerRunning
// stop UI updates
self.stopTimer()
else
timerString = "0.00"
startTime = Date()
// start UI updates
self.startTimer()
isTimerRunning.toggle()
.onAppear()
// no need for UI updates at startup
self.stopTimer()
func stopTimer()
self.timer.upstream.connect().cancel()
func startTimer()
self.timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()
【讨论】:
谢谢!这很好用。我刚刚开始学习 SwiftUI(和 Swift),这段代码已经帮助我掌握了一些概念。现在我只需要弄清楚如何使用我的 ContentView 中的时间 感谢 stopTimer 方法...以上是关于SwiftUI - 如何制作启动/停止计时器的主要内容,如果未能解决你的问题,请参考以下文章
使用tabview更改选项卡时如何使SwiftUI中的计时器保持触发