使用Swift将实时秒表计时器格式化为百分之一秒

mot*_*thy 6 stopwatch time-format nstimer cadisplaylink swift

我有一个使用NSTimer以厘秒(0.01秒)更新间隔的应用程序,以字符串格式显示运行秒表为00:00.00(mm:ss.SS).(基本上克隆iOS内置秒表以集成到实时运动计时数学问题中,将来可能需要毫秒精度)

我使用(误用?)NSTimer来强制更新UILabel.如果用户按下Start,这是用于开始重复该功能的NSTimer代码:

displayOnlyTimer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("display"), userInfo: nil, repeats: true)
Run Code Online (Sandbox Code Playgroud)

这是由上面的NSTimer执行的函数:

func display() {
    let currentTime = CACurrentMediaTime() - timerStarted + elapsedTime

    if currentTime < 60 {
        timeDisplay.text = String(format: "%.2f", currentTime)
    }else if currentTime < 3600 {
        var minutes = String(format: "%00d", Int(currentTime/60))
        var seconds = String(format: "%05.2f", currentTime % 60)
        timeDisplay.text =  minutes + ":" + seconds
    }else {
        var hours = String(format: "%00d", Int(currentTime/3600))
        var minutes = String(format: "%02d", (Int(currentTime/60)-(Int(currentTime/3600)*60)))
        var seconds = String(format: "%05.2f", currentTime % 60)
        timeDisplay.text =  hours + ":" + minutes + ":" + seconds
    }
}
Run Code Online (Sandbox Code Playgroud)

将同时运行至少2个显示链接.一旦所有其他元素都在发挥作用,这种方法是否会效率太低?

当用户按下停止/暂停/重置时,不使用NSTimer更新显示.我没有找到任何直接翻译成Swift的东西.我很确定我正在使用一种效率低下的方法来强制在UIView中快速更新文本UILabel.

更多详细信息:我正在为运行的计时器格式(mm:ss.SS)编写更少杂乱的代码.完成后我会再次更新.

更新:感谢Rob和jtbandes回答我的两个问题(格式化方法和显示更新方法).用CADisplayLink()替换NSTimer(见上文)很容易:

displayLink = CADisplayLink(target: self, selector: Selector("display"))
        displayLink.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
Run Code Online (Sandbox Code Playgroud)

然后替换代码中的所有实例

displayOnlyTimer.invalidate() 
Run Code Online (Sandbox Code Playgroud)

displayLink.paused = true 
Run Code Online (Sandbox Code Playgroud)

(这会暂停显示链接的更新)

jtb*_*des 7

对于快速UI更新,您应该使用CADisplayLink.任何比显示刷新率更快的都是浪费处理能力,因为它在物理上无法显示.它还提供了timestamp前一帧的一个,因此您可以尝试预测下一帧的时间.

你正在计算CACurrentMediaTime() - timerStarted + elapsedTime多次.我建议只做一次并将其保存在局部变量中.

考虑使用NSDateComponentsFormatter.尝试重用格式化程序的一个实例,而不是每次都创建一个新的实例(这通常是最昂贵的部分).总的来说,你可以做的字符串操作越少越好.

您可以在显示方法的开头和结尾检查CACurrentMediaTime,看看它需要多长时间.理想情况下它应该小于16.6ms.请关注Xcode调试导航器中的CPU使用率(以及一般功耗).