基于 Date() 的秒表 - SwiftUI [英] Basing a StopWatch off of Date() - SwiftUI

查看:33
本文介绍了基于 Date() 的秒表 - SwiftUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的应用程序中有一个秒表,它可以完全在设备的时间之外运行.我有下面的代码,它占用按下开始按钮的时间,然后每秒更新 secondsElapsedstartTime 和当前之间的差异.我被困在实现暂停功能上.如果我只是使更新计时器无效,那么计时器将从停止的地方重新开始.关于如何做到这一点的任何想法?

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()
            }
        }
    }
}

推荐答案

是的.操作方法如下:

  1. 按下暂停键时,记下当前时间并计算计时器的已用时间.使更新计时器无效.
  2. 当计时器恢复时,取当前时间并减去已用时间.设置 startTime 并重新启动更新计时器.
  1. When pause is pressed, note the current time and compute the elapsed time for the timer. Invalidate the update timer.
  2. 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 以避免丢失更新.
  • 我添加了 pausedrunning 状态变量,以防止按钮被连续按下一次以上.
  • I changed the timer interval to 0.1 from 1 to avoid missing updates.
  • I added paused and running state variables to keep the buttons from being pressed more than once in a row.

这篇关于基于 Date() 的秒表 - SwiftUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆