UIViewController not added to the view controller hierarchy after performSegueWithIdentifier - ios

I have the following method which functions properly when the app is in foreground. The SecondViewController gets pushed to the top of the UINavigationController's view controller stack.
I have two UIViewController's FirstViewController and SecondViewController in a UINavigationController and FirstViewController is the rootViewController of the UINavigationController
1. UINavigationController *navigationController =
(UINavigationController*) self.navigationController;
2. [self.navigationController
performSegueWithIdentifier:#"showSecondView" sender:self];
3. SecondViewController * secondController = (SecondViewController*)
navigationController.viewControllers[1];
4. [secondController performSomeAction];
After pushing the SecondViewController, I pop to UINavigationController's rootViewController which is FirstViewController. This code works fine when the app is in the foreground.
I have an iOS8 interactive notification calling the FirstViewController, which pushes the SecondViewController using performSegueWithIdentifier.
Interactive Notification correctly calls the FirstViewController but the UINavigationController controller does not push the SecondViewController(see above code), even though the code correctly when the app is in the foreground.
Some Initial Investigations I did
Segue Identifier is correct
When I put the breakpoint on the fourth line on the case where the UINavigationController does not push the SecondViewController, secondController instance is a SecondViewController.
breakpoint showed that the UINavigationController only had FirstViewController even after the performSegueWithIdentifier.
No memory leak in instruments
Any help is appreciated!

Related

Objective C: How to get navigation controller from ViewController behind my current ViewController

I have ViewController 1 with navigation controller where I'd like to push some other VC. But I have ViewController 2 presented over it not in navigation controller hierarchy.
In ViewController 2 I have some methods to minimise it, but I can't reach navigation controller in ViewController 1 to push other VC there. I tried to do it from window with code:
UITabBarController *mTabBarVC = (UITabBarController *) [UIApplication sharedApplication].keyWindow.rootViewController;
UINavigationController *prevNavigationController = myTabBarVC.selectedViewController.navigationController;
But I had no success I get nil in prevNavigationController.
Create in ViewController 2.h:
#property UIViewController *parent;
In ViewController 1 pass self:
viewController2.parent = self;
In ViewController 2 you can now get UINavigationController:
UINavigationController *navVC = self.parent.navigationController;
It's the best way, because you can change structure of your view controllers in future and will get a bug.
If ViewController 2 present modally on ViewController 1, you can get VC1 from VC2 in self.presentingViewController property.

UINavigationController of UIViewController is nil, after pushViewController

I'm using the ECSlidingViewController for my navigation menu, whenever I want to push a UIViewController from this menu, the UINavigationController of the pushed UIViewController is always nil.
The UINavigationController is initialized, the NSLog output shows the following <UINavigationController: 0x8a80770> address. When I call the method pushViewController:animated the UIViewController gets pushed but the UINavigationController is nil, therefore I can't see the UINavigationBar in this controller.
Here is the code snippet I'm using for this:
RecommendationsViewController *rvc = [self.storyboard instantiateViewControllerWithIdentifier:#"RecommendationsViewController"];
[self.transitionsNavigationController pushViewController:rvc animated:NO];
self.slidingViewController.topViewController = rvc;
In viewDidLoad the transitionNavigationController get's initialized with (please note the slidingViewController is from the ECSlidingViewController project on github https://github.com/ECSlidingViewController/ECSlidingViewController and is of type ECSlidingViewController):
self.transitionsNavigationController = (UINavigationController *)self.slidingViewController.topViewController;
Thanks for any help!
I think you have misunderstood how this is suppose to work.
The UINavigationController has to be the topViewController.
Don't reassign the topViewController after you do a push. By doing this:
self.slidingViewController.topViewController = rvc;
All that is going to do is set the current window to display that UIViewController, thats why you didn't see the nav bar, the app needs to display the UINavigationController which in turn will manage a list of UIViewController's
The navigation controller handles a stack of viewControllers, just push the new UIViewController and nothing else
There is a related issue where a Navigation controller's topViewController will forget that it is attached to a navigationController.
My Storyboard setup is: ->NavigationController->ViewController
The connection between NavController and ViewController is "root view controller".
I have set a storyboardID for each of these view controllers.
I have a view management class "ViewManager" that contains weak references to all storyboard views, which I obtain using:
_rootNC = [self.mainStoryboard instantiateViewControllerWithIdentifier:#"NavController"];
//ViewController gets auto-attached to the NavController, and so viewController.navigationController == NavController
_firstVC = [self.mainStoryboard instantiateViewControllerWithIdentifier:#"ViewController"];
//Instantiating the ViewController again clears its navigationController property, and so viewController.navigationController == nil
I suppose one shouldn't gain a hook into Storyboard Instances by reinstantiating the views. I'd appreciate if others would share their best-practices for obtaining weak references to storyboard viewControllers in such a way that I could control them in a single viewManager class. (I'm leaning toward setting viewManager.rootNC from within NavigationController's viewDidLoad).

iOS UINavigationController switching rootviewcontroller based on condition

I am writing an iOS application using storyboard.
I created ViewControllerA, ViewControllerB and then embedded ViewControllerA in a UINavigationController on the storyboard.
The app will show ViewControllerA when it is first launched, otherwise it will show ViewControllerB.
I added launch history check code successfully. I am going to set the UINavigationController as the window's rootViewController in the didFinishLaunchingWithOptions method.
The problem is that I cannot get the UINavigationController from the storyboard, so I can't push ViewControllerA and ViewControllerB based on my condition.
If you're using a storyboard then the UINavigationController should be set as the initial view controller and it will be loaded and displayed automatically. Now, when something happens in ViewControllerA it can push ViewControllerB by using:
ViewControllerB *b = ...;
[self.navigationController pushViewController:b animated:YES];
For enhanced tampering, the app delegate has a window property. From here you can get the rootViewController. Cast that to the UINavigationController and you can modify / push. Set it to something else and you can replace the UINavigationController all together.

navigation controller issue in application with 2 tabs

In my application 2 tabs are there. I am adding tabbarController to the window with two view controllers viewcontroller1 and viewcontroller2 in didFinishLaunchingWithOptions. Now I need to add a button in the viewcontroller1 and in the button action i need to push a new viewcontroller nextViewController. To do this in the button action, i had created a navigation controller and sets its rootview controller as viewcontroller1 and then i push the nextViewController through that navigation controller. But the nextViewController is not getting loaded. Why?
(void) buttonAction {
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:self];
nextViewController *nextViewControllerObj = [[nextViewController alloc]init];
[self.navigationController pushViewController:nextViewControllerObj animated:YES];
}
Instead of adding first tab view controller into UINavigationController, please try adding main UITabBarController into UINavigationController in "didFinishLaunchingWithOptions".

PushViewController iOS

I have three view controllers. MainViewController, secondViewController, thirdViewController. I would like to know once I click on done button on the thirdViewcontroller,
How could I go directly yo MainViewController instead of going back secondViewController and then MainViewcontroller by using pushViewController?
Assuming that your using a navigation controller, you can pop to root by calling:
[[self navigationController] popToRootViewControllerAnimated:YES];
This will bring you back to your MainViewController.

Resources