I want to make an app that has a timer starting at 10.0000000 for example, and I want it to countdown perfectly
Here's my code so far:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var labelTime: UILabel!
var counter = 10.0000000
var labelValue: Double {
get {
return NSNumberFormatter().numberFromString(labelTime.text!)!.doubleValue
}
set {
labelTime.text = "\(newValue)"
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
labelValue = counter
var timer = NSTimer.scheduledTimerWithTimeInterval(0.0000001, target: self, selector: ("update"), userInfo: nil, repeats: true)
}
func update(){
labelValue -= 0.0000001
}
}
What happens is that my countdown is really slow, it's just not working and it would take like 1 hour to get to 0 seconds, instead of just 10 seconds. Any ideas? What changes should I make to my code?
Thanks
Timers are not super-accurate, and the resolution of NSTimer is about 1/50th of a second.
Plus, the refresh rate of the iPhone screen is 60 frames/second, so it's totally pointless to run your timer any faster than that.
Rather than trying to use a timer to decrement something every time it fires, create a timer that fires like 50 times a second, and have it use clock math to update the display based on the remaining time:
var futureTime: NSTimeInterval
override func viewDidLoad() {
super.viewDidLoad()
labelValue = counter
//FutureTime is a value 10 seconds in the future.
futureTime = NSDate.timeIntervalSinceReferenceDate() + 10.0
var timer = NSTimer.scheduledTimerWithTimeInterval(
0.02,
target: self,
selector: ("update:"),
userInfo: nil,
repeats: true)
}
func update(timer: NSTimer)
{
let timeRemaining = futureTime - NSDate.timeIntervalSinceReferenceDate()
if timeRemaining > 0.0
{
label.text = String(format: "%.07f", timeRemaining)
}
else
{
timer.invalidate()
//Force the label to 0.0000000 at the end
label.text = String(format: "%.07f", 0.0)
}
}
Are you trying to make it display every combination between 0.0000001 and .99999999 in a period of one second? The screen would literally have to update a hundred million times in order to display every number. There's no feasible way to do this in a single second on any present technology or likely any future technology. The screen itself cannot update any faster than 60 times a second, so that's the fastest this will work for you.
You can try using NSTimer for that rate (1/60 = 0.0167). NSTimer itself isn't guaranteed to be very precise. In order to update the screen at every frame, you'll have to use CADisplayLink
(https://developer.apple.com/library/ios/documentation/QuartzCore/Reference/CADisplayLink_ClassRef/).
This gives you the chance to run a selector on every frame update, which is as fast as the system can change the frame by definition.