Unbalanced calls to begin/end appearance transitions after Fullscreen Youtube Video - ios

I am approaching mental trying to solve this issue:
The situation:
I have a pretty basic application, an an MMDrawerController with a tableview inside, which links to a uitabbarcontroller when an item is pressed. Inside the first page of that is an embedded youtube UIWebView which when pressed played a youtube video fullscreen.
Here is what is happening.
Press video, opens in fullscreen and starts playing
UITabBar viewWillDisappear fires
Root MMDrawerController viewWillAppear fires
Video Ends
User back to UITabBar they started and everything seems fine even though it 'disappeared' earlier
Now I put booleans in the ViewWillAppears / Disappears of the two views to check what the current state of the app is like. Usually it's 0,1 indicating either the table is open or the uitabbarcontroller is open. After the video, they show 0,0. If I press back on the navigation I get "Unbalanced calls to begin/end appearance transitions" when navigating from wherever I am.
Right now If I listen for the start of the youtube video and then fire:
[self.navigationController popToRootViewControllerAnimated:NO];
I can prevent the unbalanced calls, from occurring and the user can continue to navigate the app. However they don't get to watch the video and they just get thrown back a view.
As well in 3. I can check for 0, 0 on the two controllers and then pretty much reboot the whole app. But thats not a good solution.
Intended outcome:
The user can press the uiwebview, watch the video, and afterwards they are returned to where they left off. If they hit back on the navigation controller, no unbalanced appearance transitions.
I've tried a bunch of stuff, like
[self.navigationController poptoViewController:...]
From what I gather at this point, it has something to do with fullscreen videos loading in the root controller (hence its viewWillAppear firing at 3.) but I'm not getting 'placed' back correctly afterwards. Something like
[self.navigationController heyTheUserIsPresentlyIn:self]
That I can call after the video goes away would be crazy good.
Any assistance is much appreciated, although I've been on this for hours and hours, If I'm a moron any links to docs or sections in books would help a lot. Thanks.

It sounds like ViewController life-cycle issue.
Are you sure you want to navigate from a UITableView to a UITabBarController? Try remove the latter because it's normally the root ViewController and calls to viewWillDisappear and viewWillAppear could be made based on this assumption.
If you need a tabbed like control which is not the root ViewController maybe consider rolling your own?

Well this happens when a sequence of navigation animation or animation started without properly ending first animation, so i can guess the same is with your animation, take care of your animation even if it is not due to Navigation controller.
Hope it helps you

Related

When is an app removed from memory

One of the tabs in my app presents blog posts. I notice that when I move to another tab or leave the app that when I return, new blog posts are not downloading. The download is kicked off by viewDidLoad() in the ViewController. It's not firing when I return to this view.
Why isn't viewDidLoad() firing when I leave the app? How long does the app remain view loaded in memory?
How should I check for new posts when the user comes back to the app or from another tab?
Thanks!
viewDidLoad may not be the best place to download the updates. If for example you push from ViewController A -> ViewController B, the first view controller (A) isn't unloaded.
You may want to put the code in viewDidAppear or viewWillAppear.
Look at ViewController LifeCycle for some reference.
You can use the applicationDidBecomeActive notification to trigger updates or whatever else you want your app to do when it is brought back from the background.
There is a good answer on this here: How can I use applicationDidBecomeActive in UIViewController?
There is also a good article on Apple's website about handling transitions from various app states here: https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StrategiesforHandlingAppStateTransitions/StrategiesforHandlingAppStateTransitions.html
ViewDidLoad is only called once when the ViewController is instantiated. In a UITavBarController, the child view controllers are only instantiated once. As you move from tab to tab, the ViewControllers are kept in memory.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITabBarController_Class/
If you background the app, then iOS will keep it in memory until it starts to get low, then starts to terminate apps.
Take a look at the delegate for the TabBar
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITabBarControllerDelegate_Protocol/index.html
This can tell you specifically when the user switches tabs. But if they flip back and forth, it could needlessly create several API requests.

Restore view state without animating segue

I have added state restoration to my app, and it seems to work fine, however I'm not happy with the way that it functions.
Basically, the app is a Disney wait time tracker, so it has a selection of the four parks when you first open the app. Tapping on one of these parks segues (with the slide up animation) to the main section of the app. The problem is - When the app is reopened and the view restores after a few seconds, the slide up segue is performed (which is quite distracting).
Anyone have any idea why that is happening?
It might be down to how you are triggering your view and what time of segue you are choosing.
Otherwise you can specify whether its animated in your segue method:
ObjectiveC
[self.navigationController pushViewController:aYourViewController animated:NO]
or in Swift:
self.navigationController?.pushViewController(yourController, animated: false)

iOS How to implement a countdown screen before the user sees the view

I was wondering what is the best way to implement a countdown screen before showing the user the game view. For a more detailed example, I want the user to see a screen that displays 3...2...1...GO ! and than the game will appear.
Currently in my application I am using a navigation controller as my main menu where you can select multiple games to choose from. When a user selects one of the game buttons this is where I want the countdown screen to appear before my game interfaces does.
Solutions that I have thought about:
1) should I implement a new view controller that i push on the navigation controller to perform the count down ( seems like a waste)
2) is there a way to blank everything on a view and show a countdown first?
Thanks in advance for your help and cooperation !
Ryan
The best way i think is as soon as user selects a game, add your 3..2..1. Go screen on the same view..as soon as u present this u can also start preparing to create your game interface(but do not present). After GO appears, remove this countdown view and present your game..
It depends on the effect you are after. If you push a view controller onto the navigation stack, you'll need to use a pop transition.
My suggestion would be to open the game view controller and put a full-screen sized overlay view on top of it with your countdown message. Have the game VC manage the countdown view. When the countdown is complete, you could fade it, shrink it to a point, do some sort of clock wipe or keyhole animation, or whatever you want, easily and simply. (Some things are obviously easier than others. Cross-fades, shrinks and the like are trivial. clock wipes and keyhole transitions are much harder and require pretty advanced Core Animation skills.
What platform will this be for? For a full screen overlay I would try UIPopoverViewController if on an iPad. Otherwise, try a view controller presented modally. I believe you can set the transparency of either type to less than 1 so the underlying view shows through. In this case it would be nice to display the selected game's opening screen during the countdown. Of course it would be dark because of the overlying view. But it would provide a glimpse into what is to come.

Sliding my view controller back in iOS 7 is very slow for only one view controller

Has anyone encountered a similar issue? I have one view controller that it lags greatly on the sliding when I pull my finger across the screen to go back, but only on about the first half of the slide. The rest goes smoothly. If so, how does this get counteracted? I honestly can't seem to find anything that might cause it. Even removing all my gesture recognizers does nothing to help it. But other view controllers slide perfectly in my app.
It's hard to say without you being more specific, but it sounds like you might be performing some intensive tasks in the viewWillAppear: function of the view controller you're returning to. If the main thread is blocked here, even for a short amount of time, it could result in this behavior.

Restart drawing and events in UIViewController (iOS)

Simplified question: Is there any way to restart the navigationController of an application?. I'm trying to force the application to get his initial appearance.
Long explanation
I've a pet project in iOS and I have a weird problem with the interface that I'd like to solve. I'd like to understand also the mechanics behind this behavior.
I've a simple welcome view, wich shows the splash screen of the application. After that, thread goes to sleep state for 1.5 seconds.
[NSThread sleepForTimeInterval: 1.5];
Then, I'm showing an advertisement view:
AdController *ad = [[AdController alloc] initWithNibName:nil bundle:nil];
[self.navigationController presentModalViewController: ad animated:YES];
[ad release];
And that's all the logic behind. After that, other controllers are pushed without incidence. I want to achieve that, if at any moment the user makes the application go to background (pushing the iPhone/iPad button) then all the controllers must disappear from the stack via pop. In order to get it I'm using applicationDidBecomeActive event from the delegate. The code is the following:
[self.navigationController dismissModalViewControllerAnimated:NO];
[self.navigationController popToRootViewControllerAnimated:YES];
This is driving to some weird visual behaviours. Depending of the moment that the user choose to push de button the transition to the first view is visible. In other cases the ad view is still present, so it is dismissed and then appears the splash screen.
It will be great if there is some way to reset this first controller (splash screen), in order to get all the transitions working as the first time. I've thought about pop it from the navigation controller and the reload another one, allocating again, but it seems a bit complicated.
Is there any simple way to achieve that?
Important Edit: If the user forces repeatedly the application to go background then these exceptions are thrown:
nested pop animation can result in corrupted navigation bar
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
The easiest way that I've found is to add to the plist file a new row with key "Application does not run in background" and with value YES.
Forces the application to be completely closed and unloaded from memory when the user pushes the button.

Resources