I was wondering how would i pause my sprite kit scene when home button is pressed.
I found few answers here and tried it with notification center like this.
When my scene load:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(applicationDidEnterBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
And then later the method that is called if enters to background:
- (void) applicationDidEnterBackground{
NSLog(#"Enter to background");
self.scene.view.paused =YES;
}
Problem here is that i get the NSLog message so applicationDidEnterBackground method is being called properly. But problem is that when I return to application my app is not on "pause" mode.
So my pause statement (self.scene.view.paused =YES;) is not being called?
If I put exact statement somewhere else in code or if I make a pause button with this statement pause works just fine.
What is the problem? Why this won't work with notification center?
Sprite kit for iOS 8 automatically resumes your game after exiting background mode. It happens after applicationDidBecomeActive is called. Also, Sprite kit for iOS 8 automatically pauses your game when it moves to the background.
Update: The following are the states of skView.paused when enter/exiting background mode for Xcode 5 and 6.
Xcode 6
Deployment targets 7.0, 7.1**, 8.0, and 8.1
applicationWillResignActive = NO
applicationDidEnterBackground = YES
applicationWillEnterForeground = YES
applicationDidBecomeActive = YES
** When I ran on a device running iOS 7.1, the states were all NO
Xcode 5
Deployment targets 7.0 and 7.1
applicationWillResignActive = NO
applicationDidEnterBackground = NO
applicationWillEnterForeground = NO
applicationDidBecomeActive = NO
By the time your application has entered the background, it's probably too late.
Instead, we should register for the UIApplicationWillResignActiveNotification notification and handle our just-before-exit code when we receive this notification.
Related
I am developing an iOS game using sprite kit with an iAd banner, and this iAd is causing the game to unpause itself, and by unpausing I mean SKActions are continuing, here are some details:
1) I have several objects in my game that have a sequence (in series not parallel) of SKActions.
2) clicking the 'pause game' button on my game's screen and 'resuming' work fine - everything is pauses as desired. NSLog statement in "Note" below not displayed.
3) I've coded the following notification which has an observer that calls a selector to pause the game (which gets called properly). NSLog statement in "Note" below not displayed.
-(BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
[[NSNotificationCenter defaultCenter] postNotificationName:#"iAdsoPauseGame" object:self];
return YES;
}
4) iAd appears lalala... everything is paused as it should be. NSLog statement in "Note" below not displayed.
5) when I click the "x" in the iAd, the following occur in this order:
a) the SKAction that my object in game was running while I 'paused' the game by going to iAd goes to completion, and the NSLog statement (in Note below) IS listed.
b) around 0.5sec later, my ViewController's "viewDidAppear" is called
c) less than 1ms after 5b, my iAd's "bannerViewActionDidFinish" is called (I have a notification here that tells my game to pause ... problem is there is this 0.5sec downtime between me closing the iAd and this method being called...)
Note: In my game's main .m file, in the "update" method (called every frame), I have an NSLog statement (below), and this does display as soon as I click the 'x' in the iAd, but then stops (when 5b/5c are called).
if (NodeGamePlay.paused==FALSE) {
NSLog(#"NodeGamePlay.paused==FALSE");
}
So my question: How can I prevent the SKaction from continuing (step that occurs in 5a) when I exit the iAd? Thank you for your time and help - this has been bugging me for quite some time!
just try this one
- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
{
skView.scene.paused = YES;
return true;
}
I am having a simple game in which if user goes to background, the game upon starting has to hide the player sprite node.
My code is as follows:
- (void)didMoveToView:(SKView *)view
{
[super didMoveToView:view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
}
- (void)appDidEnterBackground:(NSNotification *)notification
{
[self hidePlayerNode];
}
- (void)hidePlayerNode
{
[self.playerNode runAction:[SKAction fadeOutWithDuration:0.0]];
}
The problem is that when the game is launched from background, I can see the player node for a split second and then it disappears. I need to make the player node invisible, the moment it goes to background and user shouldn't see it when the app is relaunched.
I tried with UIApplicationWillResignActiveNotification but the result is the same. Also, I tried running the code inside the selector method by main thread, but same result again.
You are probably seeing the state of your app that was saved as you went into the background.
Apple docs: "When your applicationDidEnterBackground: method returns, the system takes a picture of your app’s user interface and uses the resulting image for transition animations. If any views in your interface contain sensitive information, you should hide or modify those views before the applicationDidEnterBackground: method returns."
Before iOS 8, the UIMoviePlayerControllerDidEnterFullscreenNotification notification was sent any time a media player went to fullscreen from a UIWebView. In iOS 8, this doesn't happen and some have suggested to listen for the AVPlayerItemBecameCurrentNotification notification instead. This doesn't appear to be sent from WKWebView. Listening for the UIWindowDidBecomeVisibleNotification notification doesn't work because it's fired for all windows that are added (including things like ad networks)
Bottom line, I've been working on this all night and I can't seem to figure out how to determine if a video was opened in full screen with a WKWebView. Any help would be appreciated.
Edit: To confirm, I created a blank project. Added a UIWebView and the AVPlayerItemBecameCurrentNotification listener to it and it got triggered when I played a video and it entered full screen. I switched that UIWebView to a WKWebView and that notification was no longer triggered.
This workaround seems to work on iOS8 & iPhone 6
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(windowBecameHidden:) name:UIWindowDidBecomeHiddenNotification object:nil];
return TRUE;
}
- (void)windowBecameHidden:(NSNotification *)notification {
UIWindow *window = notification.object;
if (window != self.window) { // Not my own window: assuming the video window was hidden, maybe add some more checks here.
// Add code here
}
}
I just need to do the same. I listened all notifications with this answer https://stackoverflow.com/a/7955014/1271424 and found: there are no notifications about fullscreen mode at all, except notifications about creating new window (_UIWindowContentWillRotateNotification) and about MPRemote (MPRemoteCommandTargetsDidChangeNotification).
Tested on iPad, 8.1.1
Is there an API that allows me to know when NotificationCenter will pop a notification on the top of the screen while my app is running (for example for an incoming Message or email)?
It causes a big performance glitch to my game so I'd like to pause it and unpause once the notification has disappeared. If there is no event to listen to I can only think of monitoring FPS and pausing for a few seconds if it drops below a threshold. Any other suggestions?
EDIT: My answer is only for popup notifications, not for the ones that scroll on to the top of the screen. Sorry :(
In your app delegate, the method
- (void)applicationWillResignActive:(UIApplication *)application
will be called.
And then
- (void)applicationDidBecomeActive:(UIApplication *)application
when it's time to start up again.
Question 1.
I am seeing following behavior on iphone 4 and iOS 5.0.1
register using addPeriodicTimeObserverForInterval to receive updates every 250 ms and update UI.
works well till the app goes to background. For eg. hit the home button or lock the screen,
When app comes back to foreground the player starts playback again but the updates dont fire again. If user hits the play pause button again on the UI updates start firing again.
This can be seen in the demo app from apple as well.
Question 2
Can we not mix C based Audio Session APIs with AV foundation classes? For eg. I have my C based listener registered when AudioInterruptions. But when I use AVPlayer with kAudioSessionCategory_PlayAndRecord they dont get called. When app goes to background AVPlayer pauses without the C based listener getting called.
Is this expected or can I do something? Please note that once I have disposed the AVPlayer instance and my app goes to background again wiht kAudioSessionCategory_PlayAndRecord
set as category the listener function gets invoked.
For your first problem, most likely you are not releasing the addPeriodicTimeObserverForInterval as suggested. Try putting something like this in your AppDelegate:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[_audioManager.audioPlayer removeTimeObserver:_audioManager.timeObserver];
_audioManager.isUIActive = NO;
}
and the appropriate method to restart the periodic time observer:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[_audioManager setUpTransportUI];
_audioManager.isUIActive = YES;
}
where setUpTransportUI recreates your time observer.