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."
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;
}
my question is related to touch event which is Global in app
This is my scenario,
I Have an App with 15 screens, When first screen launches the timer starts, User goes from one screen to another screen randomly, In that case i need to reset the timer, If timer reaches to (say 120 seconds ) i have to destroy the current user session and logout n starts from first screen.
The implementation code for startLogoutTimer resetLogoutTimer and stopLogoutTimer is in AppDelegate class, if User navigates to any screen and touches the screen, i need to execute the methods of startLogoutTimer, resetLogoutTimer and stopLogoutTimer based on action but without message call to AppDelegate from every class (Screen/ViewController).
Thank You.
My above Problem is Solved.
I added the below code into AppDelegate class
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(resetLogoutTimer) name:UITouchPhaseBegan object:nil];
Now where ever I touch on screen, my timer restarts.
Create category for UIView and handle touches in it.
#implementation UIView (Touch)
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
[((Appdelegate*)[UIApplication sharedApplication].delegate) resetLogoutTimer];
}
Or you cand do it the same with swizzling
Hi below two links solved my problem
iOS perform action after period of inactivity (no user interaction)
Timing Out An Application Due To Inactivity
My app is running an NSURLSession where it downloads a file. However, when the user locks the phone I cannot update the subviews on the screen. They are frozen. I have a method getting called when the phone locks via the app delegate; however, it will not update any subviews.
I have tried placing the updates on main thread or background and nothing works. I simply want to adjust visibility of certain objects but not longer can do that after screen is locked. I hope that is enough info. Any help would be awesome. Thanks guys!
This is what is getting called via the app delegate when the phone is locked
-(void)pauseDownload{
// I want to update the UI!!!!
[session invalidateAndCancel];
bytesSum = 0;
percent = 0;
[HUD hide:YES];
self.downloadButton.hidden = NO;
HUD.progress = percent;
[HUD setLabelText:[NSString stringWithFormat:#"Loading %.0f%%",(percent*100)]];
}
None of the visibility permissions will work and the objects are un responsive. My guess is that I am losing a pointer to the objects some how when the phone is locked. Can I regain them? Am I way off idk?!
Use this in loadView or viewDidLoad:
[[NSNotificationCenter defaultCenter]addObserver:self
selector:#selector(becomeActive)
name:UIApplicationDidBecomeActiveNotification
object:nil];
-(void) becomeActive
{
NSLog(#"ACTIVE");
//
}
You can update UI in viewWillAppear: life cycle view controller method:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// update UI
}
Also, read apple's doc
Once device is lock there is no certain methodology or no way to create the background process or continue download process.
The only possible way can be used is we while during the downloading process if user lock the device & app goes into background downloaded content should be saved. So once when application is again active the downloading process should start from where it stopped.
I have read over many stack overflow questions where people ask to terminate their app oppose to let it run in the background.
The main answer I found was to set the application does not run in background BOOL to YES in my info.plist
I have done this and cleaned my project but still my application runs in the background when the user presses the home button. This solution simply does not work.
What can I do to make my application quit when a user presses the home button.
My app is currently running on iOS 6.
Any help is appreciated :)
This answer is for your first comment, not the original question. Have your iPod view controller register for the UIApplicationDidEnterBackgroundNotification notification. The implementation should stop the music. This is a much better user experience than choosing to have your app terminate on suspend.
// Put this in a good place like viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(backgrounding) name:UIApplicationDidEnterBackgroundNotification object:nil];
// Handle the notification
- (void)backgrounding {
// app is leaving the foreground, stop the music
}
// In your dealloc method add:
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
I'm at my wit's end. I need to dismiss an MFMailComposeViewController when my app transitions to the background and I can't do it. It ends up creating an awkward application state.
Is there a way to handle this programmatically? Perhaps force the view controller to put the email into the Drafts folder and dismiss without animating?
EDIT:
Calls to - dismissModalViewControllerAnimated: don't work as expected.
The awkward application state I'm talking about is my main view being redrawn over top of the email composer when the application returns from the background. The modal is never dismissed and that email composer is never accessible again.
EDIT:
Code in my initializer:
// For compatibility with iOS versions below 4.0
if (&UIApplicationDidEnterBackgroundNotification != NULL)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidEnterBackgroundNotification:) name:UIApplicationDidEnterBackgroundNotification object:nil];
}
Code in my background-entry handler:
- (void) applicationDidEnterBackgroundNotification:(NSNotification *)note {
// Do some other stuff here
// According to the docs, calling the method like this closes all
// child views presented modally
[self dismissModalViewControllerAnimated:NO];
}
I have reproduced a simple application with the code you have above. The mail composer is dismissed properly when the application enters the background.
I can only assume therefore that the //Do some other stuff here section of your code is doing too much stuff and the OS is shutting you down before you have chance to dismiss the composer.
According to the docs:
You should perform any tasks relating to adjusting your user interface before this method exits but other tasks (such as saving state) should be moved to a concurrent dispatch queue or secondary thread as needed. Because it's likely any background tasks you start in applicationDidEnterBackground: will not run until after that method exits, you should request additional background execution time before starting those tasks. In other words, first call beginBackgroundTaskWithExpirationHandler: and then run the task on a dispatch queue or secondary thread.
Perhaps you should move your other stuff to a different thread or request extra time? If you remove the other stuff, does the composer dismiss correctly?