swift NSTimer userinfo
I realise you've managed to fix this but I thought I would give you a little more information about using NSTimer
. The correct way to access the timer object and hence user info is to use it like below. When initialising the timer you can create it like this:
Swift 2.x
NSTimer.scheduledTimerWithTimeInterval(4, target: self, selector: Selector("setRotateToFalse:"), userInfo: ["theButton" :tempButton], repeats: false)
Swift 3.x<
Timer.scheduledTimer(timeInterval: 1, target: self, selector:#selector(ViewController.setRotateToFalse), userInfo: ["theButton" :tempButton], repeats: false)
Then the callback looks like this:
func setRotateToFalse(timer:NSTimer) { rotate = false let userInfo = timer.userInfo as Dictionary<String, AnyObject> var tempbutton:UIButton = (userInfo["theButton"] as UIButton) tempbutton.enabled = true timer.invalidate() }
Therefore you don't need to keep a reference to the timer and avoid often nasty global variables where possible. You may run into an issue in swift if your class doesn't inherit from NSObject
where it says there is no callback defined but this can be easily fixed by adding @objc
at the beginning of the function definition.
I was just going to post this as I read over it before I posted. I noticed that I had timer.invalidate()
before userinfo so that's why it wasn't working. I will post it as it may help somebody else.
func setRotateToFalse(timer:NSTimer) { rotate = false timer.invalidate() let userInfo = timer.userInfo as Dictionary<String, AnyObject> var tempbutton:UIButton = (userInfo["theButton"] as UIButton) tempbutton.enabled = true}
macOS 10.12+ and iOS 10.0+ introduces a block based API of Timer
which is a more convenient way
func timeToRun(buttonToEnable: UIButton) { timer = Timer.scheduledTimer(withTimeInterval:4, repeats: false) { timer in buttonToEnable.enabled = true } }
A one shot timer will be invalidated automatically after it fires.
An similar convenient way for a one shot timer is using GCD (DispatchQueue.main.asyncAfter
)
func timeToRun(buttonToEnable: UIButton) { DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4)) { buttonToEnable.enabled = true }}