Pushing view controller from app delegate - ios

So recently I had to reorganize my tab bar and remove one the tabs for a view controller that I still need to access at the end of the app. I am using NSNotifications which triggers a method in the app delegate which basically switches the tab [self.myTabBar setSelectedIndex:REC_TAB];
Worked like a charm. Now that I can no longer select the tab, I'm finding I'm having trouble pushing/popping/presenting a view controller from the app delegate.
I'm new to this so any help would be appreciated.

There's no reason that you have to do it from the app delegate -- you can if you want to, but there's no need. From any view controller, you can access the window's root view controller with self.view.window.rootViewController, and change it to whatever you want. Another way is to just present a modal view controller with presentViewController:animated: from any view controller.

Related

programmatically navigate tab view controller with nested navigation controllers

I have a TabViewController setup in my iOS app with 4 tabs. Some of the tabs go to static ViewControllers while a few go to a navigation controller that the user can then dive deeper into.
My problem is this, in the app delegate, I implement the "didReceiveRemoteNotification" method, when I receive a remote notification I display a drop down notification using a library similar to this https://github.com/terryworona/TWMessageBarManager
I would like the simplest and cleanest way to add a callback to one of these drop down messages such that when clicked I display a particular index in the tab view regardless of where I am in the app.
I have thought of possibly having the app delegate broadcast a notification that the currently displayed view controller would listen too, then have the currently displayed view controller unwind if it is nested in a navigation controller to the top level, i.e. the level where the TabViewController would be displayed and then change the tab view controller's index. Or if the TabViewController was currently displayed, it would capture the notification and simply change index. But this seems conceptually intrusive because now my ViewControllers themselves must have knowledge about where they are in the UI hierarchy, and all ViewControllers (which there are many) must implement functionality to deal with the notification so they can decide to unwind + set tab index OR simply set tab index.
I would subclass the TabBarController, and you could add a method like -(void) receiveMessageBarNotification:(NSNotification*)notification. The TabBarController already has references to your view controllers and so can handle all the logic of 'navigation controller stack vs static VC'. Then it would call the unwind segue on the view controller (if necessary) and change its own index.
The notification registration could all be handled by the AppDelegate.

iOS custom view across all view controllers

I would like to have custom view set in one screen and have it across all view controllers in my application.
I find solution with using Container view. So I create RootViewController and I give it Container view and set my original MainViewController as embed in container. I added view to RootViewController and in first view controller (MainViewController) it looks good.
The problem is when I go to another view controller by Push segue. New view controllers covers whole screen (which is okay) and covers custom view too. I was thinking that it could help if I add Navigation Controller with root MainViewController and this navigation controller would be embed in RootViewController but the result is same. I set Navigation bar as hidden (same for status bar) because I want to be hidden.
So where could be problem? Or how would you add custom view to all screens? This custom view should work as global (I am using NSTimer and counting time) so I solution with inheritance isn't for me.
You can use application window and add this custom view as subview whenever required. I have used it in one of my app to show notifications (if there area any) and it works great.
Get handle to Application Window and add subview to it. Custom view can be created from a singleton class or App delegate.
You could try it the other way round. Make a view which will never change inside your root view controller and a container view and just change the content of the container view depending what u want to display next to your unchanging view.

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.

How to determine which view controller is currently active/the one displaying a view?

In my app I am queueing some local notifications, when they fire I must present a modal view. The trouble is I have numerous view controllers any one of which could currently be active and thus the one that needs to present the modal view controller. How can I determine which one is currently in use?
I am setting a navigation controller as the windows root view controller, and this can push any number of other view controllers, some of them themselves may also be currently presenting another view controller modally.
This must work on iOS 4 and 5.
I have a lot of view controllers so would like to avoid putting code in each of them to each check if they are currently the top one.
You can look at the navigation controller's topViewController property to find out which controller is at the top of the stack. This will be the one whose view is displayed.
Since you may also be presenting a modal view controller, you'll probably be more interested in the visibleViewController property, which will give you the controller for the current view whether its presented modally or pushed onto the navigation stack.
Create a variable that stores a pointer to the ViewController that was most recently pushed. Every time you push a new ViewController, update this variable. Then you'll always know which one is on the top!

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