I have an app using an NSTimer at centisecond (0.01 second) update intervals to display a running stopwatch in String Format as 00:00.00 (mm:ss.SS). (Basically cloning the iOS built-in stopwatch to integrate into realtime sports timing math problems, possibly needing millisecond accuracy in the future)
I use (misuse?) the NSTimer to force-update the UILabel. If the user presses Start, this is the NSTimer code used to start repeating the function:
displayOnlyTimer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("display"), userInfo: nil, repeats: true)
And here is the function that is executed by the above 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
}
}
There will be at least 2 display links running at the same time. Will this method be too inefficient once all other elements are in play?
The display is then updated without using NSTimer when the user presses stop/pause/reset. I didn't find anything that directly translated into Swift. I'm fairly certain I'm using an inefficient method to force update the text UILabel quickly in the UIView.
More Details:
I'm working on less messy code for the running timer format (mm:ss.SS). I will update this once more when I've finished that.
UPDATE: Thanks to Rob and jtbandes for answering both of my questions (formatting method and display update method).
It was easy to replace the NSTimer (see above) with CADisplayLink():
displayLink = CADisplayLink(target: self, selector: Selector("display"))
displayLink.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
And then replace all instances in code of
displayOnlyTimer.invalidate()
with
displayLink.paused = true
(this will pause the display link from updating)
See Question&Answers more detail:
os