How to preserve a navigation controller's state? (pre iOS 6) - ios

I have a button in my root view controller (R) that triggers a segue to a navigation controller (N). Inside the navigation controller I can switch between all the view controllers (N.0, N.1, N.2, ...) on its navigation stack and all of these view controllers have a button to immediately jump back to the root view controller (R).
I want to achieve that - whenever the button in the root view controller (R) is hit - the navigation controller (N) shows up again with its previous configuration.
Example: If the last visible view controller before dismissing the navigation controller was (N.1) I want the navigation controller to show (N.1) again.
Currently whenever I trigger the segue from the root view controller (R) to the navigation controller (N) it's always the navigation root view controller (N.0) that shows up. (Does iOS instantiate a new navigation controller every time the segue is triggered? Or is it still the same object?)
How do I preserve the navigation controller's state and restore it when the navigation controller is presented again?
(I know that in iOS 6 there is a restorationIdentifier property which can be used for this purpose. However I want my app to support devices running iOS 5 a well and there must have been some way to achieve this behaviour prior to iOS 6.)

A segue ALWAYS creates a new instance of the destination view controller. Presumably you "jump" to the root controller with popToRootViewControllerAnimated: which presumably destroys all the popped view controllers, so there is nothing to return to. If you want to navigate a web of view controllers you won't be able to use UINaviationViewController or segues.

Related

Navigation bar is empty, created from storyboard

This is my story board:
Whenever I jump to a view controller embedded in navigation controller, the navigation bar is shown but empty, why?
The sequence I created it is:
connect buttons with destination view controllers
embed destination view controllers in navigation view controller
And the segue I use is present modally - cross dissolve.
The First root controllers of a navigation controller won't have any Back button attached to its navigation bar. You should add an additional View Controller next to any root View Controller of Navigation Controller with Push Segue ( or Show Segue for newer IOS ) to navigate between them.
I tested different segue transition methods with test projects, the answer I got is: if you are transitioning by presenting it modally, you don't get the back button, you only get it by push.

In iOS is the Initial View Controller always the same as the Root View Controller

In the 'Start Developing iOS Apps Today' guide by Apple it says that, "the first item added to the [navigation] stack is the Root View Controller and is never popped off the stack." Later on in the same section it goes on to say, "one of the view controllers is marked as the Initial View Controller ... this is the view controller that will be displayed the first time the app is launched."
My question is are the Initial View Controller and the Root View Controller always the same thing or can they be different? For example, if you created a game where the Root View Controller was the view where you played the game could you have a different controller (maybe the start screen) be the Initial View Controller, and how would this work?
For example, if you created a game where the Root View Controller was
the view where you played the game could you have a different
controller (maybe the start screen) be the Initial View Controller,
and how would this work?
Let's say for the sake of argument that the game uses a navigation controller to manage its various view controllers. In that case, the nav controller would likely be the initial view controller as well as the window's root view controller. The game board view controller might then be the nav controller's root view controller.
If you wanted to show a "game start" view controller at the beginning of the game, there are at least three reasonable options:
Make the game start view controller the nav controller's root and push the game board controller onto the nav stack when the user starts the game.
Present the game start view controller modally, and dismiss it when the user wants to start the game.
Make the game start view controller the initial view controller (and the window's root view controller), and then present the navigation controller (with the game board view controller as it's root) modally.
So no, the "initial" view controller doesn't need to be the view controller that the user actually sees first, it's just the one that's loaded first from the storyboard. It may contain other view controllers, or it might cause some other view controller to be presented immediately.
There are two root view controllers in play here:
Your application's key UIWindow's rootViewController. (Most apps only have one UIWindow but some have more than one.)
A UINavigationController's root view controller (the first object in its viewControllers array).
The Initial View Controller in a storyboard will typically be set as your key window's root view controller (#1), although this too has exceptions.
If that happens to be a navigation controller (this is common), then that navigation controller will have its own root view controller (#2).
The initial view controller is associated with the storyboard which does the work for you in terms of making that the root view controller of the window.
You can have further root view controllers inside your application but these are secondary and separate to the window's root view controller.

Single View Template add navigation

So I started out an app by selecting the single view application template. I have added some more views using storyboard and everything was working good but I now wanted a button to take the user back to the first view using [ self.navigationController popToRootViewControllerAnimated:NO]; but the issue being the template started out as just a viewController. Is there a way to turn the first view into a navigation or root view to make this work or do I have to start all over in a page application template??
Insert a navigation controller in your storyboard before your root view controller.
Set the navigation controller as your initial view controller.
Set the navigation controller's root view controller to what was originally your first view controller.

Launching with one ViewController on navigation stack

I'm trying to achieve the effect similar to the native Mail application in iOS 7 where the initial view controller on launching already has the "Mailboxes" view controller in the back stack. Any ideas on how to accomplish this? Either Storyboard or programmatic would be fine.
In the app delegate didFinishLaunching I've tried creating an initial view controller (A) embedded in a navigation controller and then pushing a new view controller (B), and then setting that new view controller to be the window's root view controller but when B appears it doesn't have a navigation bar.
You shouldn't set that new view controller to be the window's root view controller, the navigation controller should be the window's root view controller. Just push that second controller with no animation, and that's all you should have to do.

What is the difference between Modal and Push segue in Storyboards?

Can someone explain to me what is the exact difference between modal and push segue?
I know that when we use push the segue gets added to a stack, so when we keep using push it keeps occupying memory?
Can someone please show me how these two are implemented?
Modal segues can be created by simply ctrl-click and dragging to destination but when I do that with the push my app crashes.
I am pushing from a button to a UINavigationController that has a UIViewController.
A push Segue is adding another VC to the navigation stack. This assumes that VC that originates the push is part of the same navigation controller that the VC that is being added to the stack belongs to. Memory management is not an issue with navigation controllers and a deep stack. As long as you are taking care of objects you might be passing from one VC to another, the runtime will take care of the navigation stack. See the image for a visual indication:
A modal Segue is just one VC presenting another VC modally. The VCs don't have to be part of a navigation controller and the VC being presented modally is generally considered to be a "child" of the presenting (parent) VC. The modally presented VC is usually sans any navigation bars or tab bars. The presenting VC is also responsible for dismissing the modal VC it created and presented.
Swift 3.0 and XCode 8.2.1 update
1. Push Segue
Push segue has been renamed as Show segue. To create push segue, the parent view controller needs to be embedded in navigation controller. The navigation controller provides navigation bar. Once you connect two view controller with push segue, the child view controller will automatically has navigation bar on top. The child view controller will be added on top of the navigation stack.
Push segue also provides default features. The child view controller will have a back button that gets you back to the parent view controller. You can also swipe right to pop the child view controller. The animation for push segue is like sliding pages horizontally.
While you are allowed to make a push segue from a view controller that is not in a navigation controller, you will lose all the features like navigation bar, animation, gesture etc when you do so. In this case, you should embed your parent view controller inside navigation view controller first and then make push segue to child view controllers.
2. Modal Segue
A modal segue (i.e. present modally), on the other hand, is presenting over the current view controller. The child view controller will not inherit navigation view controller so the navigation bar will be lost if you present modal segue from a view controller with navigation view controller. You have to embed the child view controller in navigation controller again and start a brand new navigation stack if you want it back. If you want to get back to parent view controller, you have to implement this by yourself and call dismiss from code.
Animation for modal segue is that the child view controller will comes up from the bottom of the page. The navigation view controller is also gone in this demo
The push view must be built in a navigationController.
Click on your master view, then in the menu bar choose:
EDITOR->embed in->navigationController
This is pushing controls using custom push and segue methods for storyboard
And Modal is way to navigate through views without using Storyboards.

Resources