How to Pause and Restart Nstimer.Scheduledtimerwithtimeinterval in Spritekit [Swift] When Home Button Is Pressed

How to pause and restart NSTimer.scheduledTimerWithTimeInterval in spritekit [SWIFT] when home button is pressed?

You can use NSNotificationCenter for that will fire a notification when you app enter into background or foreground as shown into below code:

var testEnemy : NSTimer?

override func didMoveToView(view: SKView) {
/* Setup your scene here */
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("appEnterIntoBackGround:"), name:UIApplicationDidEnterBackgroundNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("appBecomeActive:"), name:UIApplicationWillEnterForegroundNotification, object: nil)

testEnemy = NSTimer.scheduledTimerWithTimeInterval(1.2,
target: self,
selector: "timerUpdate",
userInfo: nil,
repeats: true)
}

And below is the helper methods:

func timerUpdate() {
print("called")
}

func appEnterIntoBackGround(notification : NSNotification) {
print("App is in Background")
testEnemy!.invalidate() //remove timer here when add enter into background.
}

func appBecomeActive(notification : NSNotification) {

print("App is active now")
//add your timer again when app enter into foreground
testEnemy = NSTimer.scheduledTimerWithTimeInterval(1.2,target: self,selector: "timerUpdate",userInfo: nil,repeats: true)

}

Pause NSTimer on home-button-press and start them again once the app is in foreground

Pausing of NSTimer is not a native feature in objective-c or swift. To combat this, you need to create an extension, which I happen to have created and will share for you. This will work for both OS X and iOS

import Foundation
import ObjectiveC

#if os(iOS)
import UIKit
#else
import AppKit
#endif

private var pauseStartKey:UInt8 = 0;
private var previousFireDateKey:UInt8 = 0;

extension NSTimer
{
private var pauseStart: NSDate!{
get{
return objc_getAssociatedObject(self, &pauseStartKey) as? NSDate;

}
set(newValue)
{
objc_setAssociatedObject(self, &pauseStartKey,newValue,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN);
}
}

private var previousFireDate: NSDate!{
get{
return objc_getAssociatedObject(self, &previousFireDateKey) as? NSDate;

}
set(newValue)
{
objc_setAssociatedObject(self, &previousFireDateKey,newValue,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN);
}
}

func pause()
{
pauseStart = NSDate();
previousFireDate = self.fireDate;
self.fireDate = NSDate.distantFuture() ;
}

func resume()
{
if(pauseStart != nil)
{
let pauseTime = -1 * pauseStart.timeIntervalSinceNow;
let date = NSDate(timeInterval:pauseTime, sinceDate:previousFireDate );
self.fireDate = date;
}

}
}

Then when you need to use it, simply call timer.pause() and timer.resume() You of course have to keep track of your timers in your gamescene object to do this, so make sure that timer is a variable accessible for the entire class, and when making your timer, you do timer = NSTimer.schedule...

At the beginning of your class:

var spawnBulletsTimer : NSTimer?;
var spawnMeteorsTimer : NSTimer?;
var onTimer: NSTimer?;

When creating the timers:

spawnBulletsTimer = NSTimer.scheduledTimerWithTimeInterval(0.2, target:     self, selector: Selector("SpawnBullets"), userInfo: nil, repeats: true)

spawnMeteorsTimer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("SpawnMeteors"), userInfo: nil, repeats: true)

onTimer = NSTimer.scheduledTimerWithTimeInterval(timeInterval, target: self, selector: Selector("onTimer:"), userInfo: nil, repeats: true)

Then when you need to pause:

onTimer?.pause() 
spawnBulletsTimer?.pause()
spawnMeteorTimer?.pause()

Then when you need to resume:

onTimer?.resume() 
spawnBulletsTimer?.resume()
spawnMeteorTimer?.resume()

How can I pause and resume NSTimer.scheduledTimerWithTimeInterval in swift?

You need to invalidate it and recreate it. You can then use an isPaused bool to keep track of the state if you have the same button to pause and resume the timer:

var isPaused = true
var timer = NSTimer()
@IBAction func pauseResume(sender: AnyObject) {
if isPaused{
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("somAction"), userInfo: nil, repeats: true)
isPaused = false
} else {
timer.invalidate()
isPaused = true
}
}

Unable to pause Game Scene when home button pressed

You can set an observer for UIApplication.willResignActiveNotification like this, without using your custom notification:

let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil)

@objc func appMovedToBackground {
// You will need to pause the game here, save state etc.
// e.g. set SKView.isPaused = true
}

This page from Apple contains more information. It states that SKView.isPaused should be set automatically when an app is sent to the background.

One point to consider. If the nodes’ movement is based on a timer relative to an absolute point in time, this would have the effect of updating the positions as if they had been moving while in the background.

Finally, are you calling isPaused on the SKScene?

How to make iPhone application go to pause menu when home button is clicked?

The Appdelegate.m of your app provides functions you can use to track if the Application will be entering the background;

User pressed the button;

- (void)applicationWillResignActive:(UIApplication *)application

Application is in the background;

- (void)applicationDidEnterBackground:(UIApplication *)application

Within any of these functions you could set the BOOL to True/YES. -> See the comments provided by Apple within the functions for their exact usage.

When the application becomes active again, the appdelegate will (again) fire a function;

- (void)applicationDidBecomeActive:(UIApplication *)application

Swift, SpriteKit - Pause whole script

Pausing within the GameScene

Pausing the scene:

self.paused = true (self is the GameScene).

Pausing the view (SKView):

self.view?.paused = true

Pausing within the GameViewController

Pausing the scene:

let skView = self.view as! SKView
skView.scene?.paused = true

Pausing the view (SKView):

let skView = self.view as! SKView
skView.paused = true

To unpause just set paused property to false.



Related Topics



Leave a reply



Submit