基于 Date() 的秒表 - SwiftUI [英] Basing a StopWatch off of Date() - SwiftUI
问题描述
我想在我的应用程序中有一个秒表,它可以完全在设备的时间之外运行.我有下面的代码,它占用按下开始按钮的时间,然后每秒更新 secondsElapsed
为 startTime
和当前之间的差异.我被困在实现暂停功能上.如果我只是使更新计时器无效,那么计时器将从停止的地方重新开始.关于如何做到这一点的任何想法?
I am wanting to have a stopwatch in my app that runs completely off the device's time. I have my code below which takes the time in which the start button is pressed, and then every second updates the secondsElapsed
to be the difference between the startTime
and current. I am getting stuck on implementing a pause function. If I just invalidate the update timer, then the timer will restart having pretty much carried on from where it left off. Any ideas on how this could be done?
class StopWatchManager: ObservableObject{
@Published var secondsElapsed = 0
var startTime: Date = Date()
var timer = Timer()
func startWatch(){
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true){ timer in
let current = Date()
let diffComponents = Calendar.current.dateComponents([.second], from: self.startTime, to: current)
let seconds = (diffComponents.second ?? 0)
self.secondsElapsed = seconds
}
}
func pauseWatch(){
timer.invalidate()
}
}
我使用以下代码显示秒表:
I display the stopwatch using this code below:
struct ContentView: View {
@ObservedObject var stopWatchManager = StopWatchManager()
var body: some View{
HStack{
Button("Start"){
stopWatchManager.startWatch()
}
Text("\(stopWatchManager.secondsElapsed)")
Button("Pause"){
stopWatchManager.pauseWatch()
}
}
}
}
推荐答案
是的.操作方法如下:
- 按下暂停键时,记下当前时间并计算计时器的已用时间.使更新计时器无效.
- 当计时器恢复时,取当前时间并减去已用时间.设置
startTime
并重新启动更新计时器.
- When pause is pressed, note the current time and compute the elapsed time for the timer. Invalidate the update timer.
- When the timer is resumed, take the current time and subtract the elapsed time. Make that the
startTime
and restart the update timer.
这是更新后的代码:
class StopWatchManager: ObservableObject{
@Published var secondsElapsed = 0
var startTime: Date = Date()
var elapsedTime = 0.0
var paused = false
var running = false
var timer = Timer()
func startWatch(){
guard !running else { return }
if paused {
startTime = Date().addingTimeInterval(-elapsedTime)
} else {
startTime = Date()
}
paused = false
running = true
timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true){ timer in
let current = Date()
let diffComponents = Calendar.current.dateComponents([.second], from: self.startTime, to: current)
let seconds = (diffComponents.second ?? 0)
self.secondsElapsed = seconds
}
}
func pauseWatch(){
guard !paused else { return }
timer.invalidate()
elapsedTime = Date().timeIntervalSince(startTime)
paused = true
running = false
}
}
注意事项:
- 我将计时器间隔从
1
更改为0.1
以避免丢失更新. - 我添加了
paused
和running
状态变量,以防止按钮被连续按下一次以上.
- I changed the timer interval to
0.1
from1
to avoid missing updates. - I added
paused
andrunning
state variables to keep the buttons from being pressed more than once in a row.
这篇关于基于 Date() 的秒表 - SwiftUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!