How to go back to the first view - ios

Assuming i have a setup like the above, how would one go back to the first view (eg. The one with the Label) ?
I am asking this because i am not sure if is there a particular reason why there would be multiple navigation controllers setup similar to above.
I came across this problem because popToRootViewController will only go back to the first view of that navi controller. Eg. if i was at one the views of the 2nd navigation controller and i were to run popToViewController, it will only go back to the first view controller of the 2nd navigation controller. I have since solved the problem by removing the other navigation controller but my curiosity had to be resolved.

As I stated in the comment, the second view controller is almost certainly unnecessary (but this isn't entirely necessarily the case), so your best bet is most likely to simply to remove that second navigation controller.
With that said though, how you would get back to the original view controller with the existing set up would depend largely on how you got to the current view controller.
If the second navigation controller is pushed on to the first navigation controller's navigation stack, then from any view after the second view controller, you could do something like this:
self.navigationController?.navigationController?.popToRootViewControllerAnimated(true)
Otherwise, if the second navigation controller were presented modally, you could dismiss it from any of the view controllers in its navigation stack with the following code:
self.navigationController?.dismissViewControllerAnimated(true, completion: nil)
It's important to remember that UINavigationController is a subclass of UIViewController and as such, any method we can call on the latter can also be called on the former.

One simple (Hacky) approach is to maintain a global pointer to your first navigation controller (Maybe in the AppDelegate or .pch file), and whenever you want to go your root controller, you can just say dismissViewController:animated, and then popToRootViewController.
Should work in all the cases.

Related

Dismissing and presenting View Controllers - An Explanation?

Recently, I've been reading about the concepts behind dismissing and presenting View Controller. I've been able to pick up on the ideas of dismissing the previous View Controller from the destination View Controller but I can't find an answer to a few questions that have been on my mind for quite a bit.
Scenario 1: I have a login page and after the user enters their credentials, it performs a segue to another View Controller. Is it necessary to dismiss the login page afterwards or is there no reason to?
Scenario 2: I have two normal View Controllers (VC1 and VC2). If I perform a segue to VC2, will I need to dismiss VC1?
I'm mainly confused regarding the idea of when it is necessary to dismiss View Controllers and when it is not necessary to do so.
I'd appreciate it if anybody could help clear these questions up for me.
Scenario 1: After performing a segue, it switches between your view controllers [ automatically dismisses the current ViewController and presents a new one ].
So, there's no reason to dismiss the login page.
Scenario 2: No you don't need to dismiss VC1.
1) When you go from login controller to second controller you just need to present the second controller and no need to dismiss first because if you are using navigation controller as a part of your segue all the view controllers are arranged in form of a stack . So second comes on top and first goes below it.Now if you need to got from second to first you can either dismiss your controller or pop your controller.When you dismiss a controller it is not popped from stack instead just moves behind and let the first controller come on top and when you pop a controller it removes itself from stack as well.
2) Same goes for your second question no need to dismiss first when you go from first to second controller.
If there is a view controller which in most cases will be used only once (like login or settings etc.) — and especially if, after you’re done with it, it makes sense to return to the view controller you were on before — the best is to present it modally and dismiss it when you’re done. The rest of your view controllers stay in memory after the user can no longer see them, and this is expected behavior given the way Apple has created the methods for presenting and dismissing view controllers.
It is my understanding that in the Android world, this is not the case -- the default there is that when a new view controller is presented, the old one really does goes away.
As you know once user has signed in, log in screen not opens until user log out. So you should remove log in view controller from stack, it should not keep in memory. For this task, do not directly perform segue, you should change root view controller. There are lot of answers on stackoverflow for How to change root view controller?

Functional difference, UINavigationController vs Only Storyboard Segue

So UIKit Framework Reference describes UINavigationController as an efficient way to present data and views to user. But I'm curious as to the performance and manageability differences between using UINavigationController VS SegueOnly.
There must be certain situations that one is better-suited than the other. I am entirely new to coding but instinctually I imagine UINavigationController is more for presenting VC's that each have a lot going on and user spends much time on each VC equally or that multiple VC's need to be running and holding data at same time. And that Segue are more for Uni-directionally VC progression or short-use, low-data VC presentations. Are any of these assumptions correct?
What are the PROS to implementing a UINavigationController?
This is an Apples to Socket-wrenches comparison. A navigation controller versus a segue isn't even an option. They don't fill the same role. You can use a navigation controller with or without using segues. You can use segues with or without a navigation controller.
A UINavigationController is a specific type of view controller. Specifically, it is designed for controlling a navigation stack of view controllers. When a user moves forward through your app, you add other view controllers to this navigation stack (either through segues or through other methods available on the view controller to present other view controllers). Meanwhile, the navigation controller allows you to "pop" controllers off the stack and we go backward to the previous view controller.
When we're comparing a UINavigationController to things, we should compare it to things like UITabBarController, or UISplitViewController, or UIPageViewController. These are other types of view controllers that control the way in which a user navigates through our app.
Segues exist as a means to get from one view controller to another. But the various controllers I just listed exist as a means for controlling the navigational relationship between your controllers.
If you are using storyboards for building your app, I highly recommend that you use segues. Whether or not you use a navigation controller is entirely up to the way you want your application navigation to work.
Perhaps some pictures might make the distinction more clear?
Exhibit A
Here we have two view controllers. No navigation controller, nothing. Just two normal controllers. The line with the arrow between the view controllers is the segue. The segue defines a relationship between the view controllers which lets us get from the one on the left to the one on the right.
Exhibit B
Here we have a navigation controller, followed by two view controllers. The line between the navigation controller (far left) and the first view controller (middle) is not a segue. However, it does define a relationship between the navigation controller and the view controller. It defines the view controller as the navigation controller's root view controller. Whenever we present this navigation controller, it will in turn present this view controller as the first controller on its navigation stack. The line between the first view controller (middle) and the second view controller (far right), however, is a segue. It's identical to the segue from exhibit A (except exhibit A is probably a different type of segue). This segue defines a relationship between the first and second view controller and provides us with a means of getting from first to second.
Exhibit C
Here we have a tab bar controller (far left) and four view controllers. We also have a bunch more lines connecting these things. Much line in the navigation controller example, the lines between the tab bar controller and the view controllers are NOT segues, but they do define a relationship between the tab bar controller and the view controllers. These lines assign the view controllers as part of the tab bar controller's viewControllers array, which determines what tabs to display. The lines between the left view controllers and the right view controllers, however, are segues, exactly the same as the first two examples.
A segue is nothing more than a way of defining a navigational relationship between two view controllers on your storyboard. If you weren't using a storyboard, you also wouldn't be using segues at all, but you could still make your app navigate in the exact same manner (this can all be achieved programmatically without the storyboard and without segues--and I don't think it effects performances on way or another).
Whether or not to use a navigation controller is another question and an entirely separate question at that. Whether or not to use a navigation controller isn't even remotely in the same ballpark to whether or not you're using segues. Using a navigation controller also isn't a question of performance. The overhead for using a navigation controller is extraordinarily minor. Most of the overhead for it probably comes from the UI stuff it adds... but if you want that UI stuff, you're going to have that overhead whether or not you have a navigation controller.
Importantly, whether or not to use segues isn't a question of performance--it's merely a question of whether or not you're designing your app using storyboards. And equally importantly, using navigation controllers isn't a question of performance--it's a question of how you want your app's navigation to look and feel. "Is a navigation controller the right look and feel for your app?" is literally the only question you have to answer when deciding whether or not to use a navigation controller.

Use of differenct view controllers

i'm curious about what's the best way to plan the controllers for my app.
i want my main screen to have 3 button.
1) should open a nav controller with details view
2) should open a controller with other buttons that lead to others controllers
3) should open a tab bar with 2 pages ( or eventually use a switch to change page instead of the tab bar)
this is the schema of what i want
http://i59.tinypic.com/2rrvrd4.png
Is it a correct schema or i should use my controllers differently? will apple reject an apple with such schema?
thanks
As #Fogmeister pointed out in the comments, going for a UITabBarController as the main interface for your app actually seems to be a more appropriate solution here.
However, you can go with the interface that you described, but then you should keep in mind that with your current setup, you are not only using UINavigationController in the first case, but your whole navigation system is still built upon UINavigationController in the following way:
Your app has one instance of UINavigationController.
Your initial UIViewController (the one with the three buttons), is the rootViewController of your UINavigationController.
You can navigate to the other view controllers using [self.navigationController pushViewController:newViewController] (or performSegue if you prefer using Storyboards).
In the case of your third view controller, you are pushing a UITabBarController onto the navigation controller's view controller stack, this UITabBarController needs to be initialized with the two view controllers that it is going to display before it gets pushed onto the stack.

iOS View Controller Containment Parent/Child calls dance

I am trying to make a container view controller that works similarly to navigation controller. When I add something to the stack what do I do with the view controller that is a already there?
It is still my child but I don't want it's view in the view hierarchy. Should I call removeFromParentViewController on it, and just keep a separate stack with it, in that stack? So when the view above is popped off, I can check what view I should push back in order to go back to previous one.
Or should I just remove its view, without removeFromParentViewController call, and add another child controller, and its view to container view hierarchy?
Basically what do I do with the controllers that aren't on the screen?
The "stack" is just an array that a navigation controller uses to keep track of its view controllers. If you're building your own, you will need to have an array also. The way a navigation controller works, when a controller is pushed, that controller is added to the array, and if one is popped, that one is removed from the array. When you do a transition, the one that's going off screen should call removeFromParentViewController, so it's no longer in the hierarchy (but if it's going away because of another one being pushed, you would leave it in your array -- that's how the controller knows which one to go back to on a pop). You should use transitionFromViewController:toViewController:duration:options:animations:completion: to do your transitions from one controller to the next.

Displaying a Specific View in a UINavigationController Stack

In building my application which is a tab based application, from the first tab, the user has the option to view their profile information (which is specific to the app). SO have set up UINavigationController with following view controllers:
1 - Edit profile
0 - View profile (also the root view controller for the `UINavigationController`).
The flow I would like to achieve is if a profile has not been set up (i.e. the first time the application is run), I would like to go directly the Edit Profile View, which right now is the default behaviour since that view is at the top of the stack.
The problem I have run into is, if the profile has been set up, how would I go directly to View Profile. I have looked at the documentation for the UINavgationController, and it unclear about popping a view controller off the stack. The method popToViewController:animated return an NSArray of items popped from the stack. Does that mean those view controllers are no longer available, and/or is there a better method to go directly to the view controller that I want?
If you only have two views in the navigation controller, and View is the root view controller, you can make sure that View is the one that is shown by running popToRootViewControllerAnimated: immediately before or after that tab has been selected on the tab bar controller.
If you are in a case where you want Edit to show, run popToRootViewControllerAnimated: followed by pushViewController:animated: with the Edit view controller.
When you want to pop, you can use popViewControllerAnimated: rather than popToViewController:animated. (You only have two view controllers in this nav controller, so ther is only one that will ever be popped.)
This seems pretty simple, unless I have misunderstood your question.
The array of view controllers that are returned from the popToViewController:animated aren't needed by most programs. I haven't really found a need to use this method myself, and, as I said, it doesn't look like you need it here.

Resources