How to execute function after animation completion in Swift for WatchKit - animation

I'm trying to create a simple animation in watch kit and i don't find the helpful "completion" that allows to perform a method at the end of the animation.
In the code the updateLabel is executed at the same time of the animation.
Here is the code:
var timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: Selector("someSelector"), userInfo: nil, repeats: false)
func testSequence() {
arcImage.setImageNamed("test")
arcImage.startAnimatingWithImagesInRange(NSMakeRange(1, 30), duration: 3, repeatCount: 1)
updateLabel()
}
func updateLabel() {
label.setText("update")
}

Knowing the duration of the animation, could use a NSTimer to call a method after the duration of the animation is completed.
var nsTimerObject:NSTimer = NSTimer.scheduledTimerWithTimeInterval(timeInSeconds, target: self, selector: "methodToBeCalled", userInfo: nil, repeats: false)

Related

Using pause with a NSTimer but the gap is too big Swift 2.0

My last bug before uploading (Fingers Crossed). I am using a NSTimer and then invalidate it when I have paused the game. However, when it resumes it gives a larger gap. If I comment out the invalidate and just use the scene!.view!.paused = true code then gives me a shorter gap.
I may be able to do it differently but I want to try and find the solution for this. I have learn this way and am comfortable with it.
if touch.name == "pause" {
pause.hidden = true
play.hidden = false
timer.invalidate()
scoreTimer.invalidate()
scene!.view!.paused = true
}
if touch.name == "play" {
pause.hidden = false
play.hidden = true
scene!.view!.paused = false
scoreTimer = NSTimer.scheduledTimerWithTimeInterval(1.1, target:
self, selector: #selector(GameScene.updatescore), userInfo: nil, repeats: true)
timer = NSTimer.scheduledTimerWithTimeInterval(2.5, target:
self, selector: #selector(GameScene.makeTraffic), userInfo: nil, repeats: true)
}

Timer stopped working after update to Xcode 7.3/Swift 2.2

After updating to Swift 2.2 and Xcode 7.3, my repeating NSTimer has stopped repeating.
let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(rotate), userInfo: nil, repeats: true)
timer.fire()
Selector fires once, then won't fire again until after window closes or is minimized.
Anyone else? Any suggestions?
Timers need to be always scheduled or invalidated in the same thread, may be you're calling it inside an async block? Try schedule it in the main queue:
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(rotate), userInfo: nil, repeats: true)
timer.fire()
})
func startTimer() {
let timer = NSTimer(timeInterval: 1, target: self, selector: #selector(MainViewController.updateLabel), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
}
This works for me in Swift 2.2
Apples documentation doesn't say anything about dispatch_async. Is there any reason to use it...just curious...still learning
Use the timerWithTimeInterval:invocation:repeats: or timerWithTimeInterval:target:selector:userInfo:repeats: class method to create the timer object without scheduling it on a run loop. (After creating it, you must add the timer to a run loop manually by calling the addTimer:forMode: method of the corresponding NSRunLoop object.)
dispatch_async(dispatch_get_main_queue()) {
self.timer = NSTimer(timeInterval:1.0, target:self, selector: #selector(self.rotate), userInfo:nil, repeats:true)
NSRunLoop.currentRunLoop().addTimer(self.timer!, forMode: NSRunLoopCommonModes)
}
It's a threading issue as well as either not properly being added or processing within NSRunLoop automatically. Manually doing this on the same thread fixed it.
Thanks everyone for help and recommendations.

how to close NSAlert after some time if no button is clicked by user

I want to close a alert Window (NSAlert) after specific period of time if user does not click on any of the buttons. Is there a way to set up a NSTimer to close the Alert Panel after some time, say 30 sec.
I just done something like that. I revised some of my codes for you here:
class ViewController: NSViewController {
var progressWindow:NSAlert!
func testOfProgressWindow() {
progressWindow = NSAlert()
progressWindow.alertStyle = .InformationalAlertStyle
progressWindow.messageText = "some notes"
let date = NSDate(timeInterval: 30, sinceDate: NSDate())
let uiUpdateTimer = NSTimer(fireDate: date, interval: 0, target: self, selector: "closeSheet", userInfo: nil, repeats: false)
let runLoop = NSRunLoop.mainRunLoop()
runLoop.addTimer(uiUpdateTimer, forMode: NSDefaultRunLoopMode)
progressWindow.beginSheetModalForWindow(self.view.window!, completionHandler: nil)
}
func closeSheet() {
self.view.window?.endSheet(self.progressWindow.window)
}
}

Switch tab bar programmatically in Swift

I have a tab bar application and i have a button on my first view which i want to when pressed switch to my second tab programmatically in the tab bar.
I can't quite seem to figure it out how to get the index etc to switch to it i've tried stuff like this.
tababarController.selectedIndex = 1
With no success.
Thats pretty simple tabBarController is declared as an optional type
var tabBarController: UITabBarController? { get }
The nearest ancestor in the view controller hierarchy that is a tab bar
controller. If the view controller or one of its ancestors is a child
of a tab bar controller, this property contains the owning tab bar
controller. This property is nil if the view controller is not
embedded inside a tab bar controller.
So you just need to add "?" at the end of it:
#IBAction func goToSecond(_ sender: Any) {
tabBarController?.selectedIndex = 1
}
Swift 3:
func switchToDataTab() {
Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(switchToDataTabCont), userInfo: nil, repeats: false)
}
func switchToDataTabCont(){
tabBarController!.selectedIndex = 0
}
Swift 4+:
func switchToDataTab() {
Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(switchToDataTabCont), userInfo: nil, repeats: false)
}
#objc func switchToDataTabCont(){
tabBarController!.selectedIndex = 0
}
The solution provided by Leo Dabus (see above) works fine for me. However - some controls have bad states. Can't fix that, but this little workaround will do you all good:
func switchToDataTab(){
NSTimer.scheduledTimerWithTimeInterval(0.2,
target: self,
selector: "switchToDataTabCont",
userInfo: nil,
repeats: false)
}
func switchToDataTabCont(){
tabBarController!.selectedIndex = 0
}
Add to Anthony's code:
func switchToDataTab(){
NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: #selector(switchToDataTabCont), userInfo: nil,repeats: false)
}
func switchToDataTabCont(){
tabBarController!.selectedIndex = 0
}
Where the selector class has been changed to
#selector(switchToDataTabCont)

NSTimer timeInterval parameter doesn't allow variable

When I use
timer = NSTimer.scheduledTimerWithTimeInterval(0.75, target: self, selector: Selector("drawInTime"), userInfo: nil, repeats: false)
it works fine but if I want to use a variable (instead of 0.75) for the timeInterval parameter
var waitTime = CGFloat(numberOMiliseconds) / 1000.0
timer = NSTimer.scheduledTimerWithTimeInterval(timeInterval: waitTime, target: self, selector: Selector("drawInTime"), userInfo: nil, repeats: false)
or
timer = NSTimer.scheduledTimerWithTimeInterval(waitTime, target: self, selector: Selector("drawInTime"), userInfo: nil, repeats: false)
then I get the following error "Swift compiler error: Extra argument 'selector' in call".
Can somebody help please?
If you look at the scheduledTimerWithTimeInterval signature:
class func scheduledTimerWithTimeInterval(ti: NSTimeInterval, target aTarget: AnyObject, selector aSelector: Selector, userInfo: AnyObject?, repeats yesOrNo: Bool) -> NSTimer
you notice that the method doesn't have an external name for the first parameter (that's default for methods), so you don't have to use the timeInterval external name.
Moreover, its expected type is NSTimeInterval, which is a typealias for Double, but you are passing a CGFloat.
So you should change your code to:
var waitTime = Double(numberOMiliseconds) / 1000.0
timer = NSTimer.scheduledTimerWithTimeInterval(waitTime, target: self, selector: Selector("drawInTime"), userInfo: nil, repeats: false)

Resources