Displaying a Specific View in a UINavigationController Stack - ios

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.

Related

How to go back to the first view

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.

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.

navigation controller stack uses too much resources

I am building an application that have an introduction at first when users do not login.
If they log in, when navigation controller will push to Home View Controller, but the Introduction View Controller is still in the stack and use a lot of resources. How can I prevent that?
You can set the navigation controllers property to array holding ur homeview controller alone. Or set the home view controller as root of navigation controller.
You can't prevent it from being there necessarily as that is a function of how you associate your views.
If you are happy with your current transitions (UI) then you should add a bit of code after the transition has completed which gets the nav controller view controllers array, removes the first object (the login / intro VC) and saves the new array.
If you want to change the transitions then you could look at presenting the login / intro as a modal so that when it is dismissed it is automatically destroyed.

iOS Storyboard Conditionally showing Views

I am currently working on a project for the iPad using Storyboards for the 1st time and I am wondering if my approach is the correct way to do this.
The first ViewController in this example is actually a split view controller.
Currently within the iPad app when a user clicks on the Export Features Button I am conditionally requesting the segue based on some code / checks I am running
[self performSegueWithIdentifier:#"subscribe" sender:self];
[self performSegueWithIdentifier:#"filterOptions" sender:self];
[self performSegueWithIdentifier:#"showExportedDoc" sender:self];
However I am not sure if I should have 3 navigation controllers and also when a user clicks on the Buy button in the subscribe View Controller it pushes to the Filter Options View which is actually nested in another Navigation Controller.
Any help / advice on this would be great as I mention I am just not sure if I am following the best approach with this.
Thanks
... and
also when a user clicks on the Buy button in the subscribe View
Controller it pushes to the Filter Options View which is actually
nested in another Navigation Controller.
Well, I think you have some misunderstanding here. The fact that the filter options view controller is embedded within a navigation controller in your storyboard doesn't mean that it will be instantiated with the UINavigationController when you're pushing it within the current navigation controller (It will be so though if you connect the segue to the UINavigationController that it's embedded into).
To answer your original question, I don't see right and wrong approach here. It all depends on the structure you would like to have. For me, I guess I would prefer to have only one UINavigationController that manages everything (set it as an initial view controller and embed your home view controller within it). This would provide a more consistent navigation experience to the user, plus more consistent look (navigation bar would be shown from the beginning).

IPad Split View Implement in Another View

I am creating a iPad App and it has several views to load data,but for one view i need to add split view. I dont need split views in other views. They are just detail pages. I search Through the net and found lots of tutorials based on iPad split view. But the problem is they all are creating a project as Split view project or they create a window base app and add slipt view to the delegate. I dont need to do that, I need to implement this split view only for one view. Is There any way to overcome this problem?
You can add the split view inside a Navigation Controller.
Even if the Split View is a container view controller and Apple recommends in the documentation that all containers should not be embedded in other containers, adding a split view inside a navigation controller works correctly and I never noticed any side effect in doing it.
Basically what you should do is:
- in the app delegate create a UINavigationController and use it as root view of your application window
- hide the navigation controller navigation bar if you don't want to see it (showing a split view with a main navbar on top is not nice looking...)
- then add your view controllers inside the navigation bar.
Example: imagine you have this application views sequence:
FIRST VIEW (full view = detail page)
SECOND VIEW (split view)
THIRD VIEW (full = detail page)
So you can represent FIRST and THIRD as standard view controllers (full screen), while SECOND will be a split view. Your app will be initialized by creating the main navigation controller, adding FIRST on it as top controller and using the main navigation controller as window's root view.
Than use the navigation controller push, pop methods to switch between these views or change the navigation controller "viewControllers" array directly if you don't want the recommended push/pop methods.
If you need to add special behavior to the navigation controller based on the type of view on top, just register your app delegate as navigation controller delegate (or a "main controller" object dedicated to this if you don't want to complicate your app delegate).
I am not 100% sure, but it seems to me that you can't use a SplitView just somewhere in your view hierarchy.
The Apple intended way is to use the SplitViewController as the top level controller. The left side of it can include a drill down mechanism with a navigation controller so you are ably to drill down hierarchies and the right side will present details for the item you select on the left side.
If you need a view with some kind of split mechanism in it, you probably have to code it yourself. Or even better: find some other mechanism you can use in your UI.
How are you switching your view hierarchies now? Maybe you could integrate your existing UI into a SplitViewController?

Resources