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.
Related
So I have a tabBar. Clicking a certain tab will take the user to a viewController which is embedded in a navigationController. In order to have the navigationController included, I instantiate the viewController using
myViewController = [storyboard instantiateInitialViewController];
rather than
myViewController = [storyboard instantiateViewControllerWithIdentifier:#"myID"];
The later code pushes the viewController but without the navigationController
This is fine up until the point I want to pass data to the instance myViewController. Thing is, I can't pass data with the instance referring to the initial viewController (which is the navigationController), but I can do it using an instance referring directly to myViewController. In other words:
This works in order to get data (but no navigationController):
viewController = [storyboard instantiateViewControllerWithIdentifier:#"experienceID"];
((ExperiencesListViewController*)viewController).experiences = self.experiences;
and this crashes if I try to add data, but gives me a navigationBar if I exclude setting data:
viewController = [storyboard instantiateInitialViewController];
((ExperiencesListViewController*)viewController).experiences = self.experiences;
Hope I explain this well enough. Let me know if there is something I need to clarify.
EDIT
My first thought was using prepareSegue but that doesn't seem to trigger when moving between the tabs. Another thought is to access myViewController through the instance in some way, but not sure how.
That's because the initial UIViewController of that particular storyboard is a UINavigationController.
A simple way to get the VC that you want is getting such UINavigationController by calling:
navController = [storyboard instantiateInitialViewController];
just like you've done, and then:
navController.childViewControllers[0]
This will return the first VC of that particular navigation controller (assuming, of course, that it contains solely the VC that it's embedded in), which is probably your ExperiencesListViewController
viewControllerA : rootViewController of navigationController
viewControllerB : will be pushed into viewControllerA's navigationController
1. In viewControllerA's viewDidLoad,
set interactivePopGestureRecognizer.delegate
self.navigationController.interactivePopGestureRecognizer.delegate = self;
2-1. push any viewControllerB. After viewControllerB's view is appear, swipe back => viewControllerB will be pop, viewControllerA will be appear again (OK)
2-2. On viewControllerA is topViewController, swipe back (nothing change because there is no more viewController in navigationController)
=> (problem!!) then push controllerB, I expect controllerB's view will be appear but there is nothing change and every tap event does not works.
how can I solve this problem?
Have you tried to remove this line ?
self.navigationController.interactivePopGestureRecognizer.delegate = self;
I don't think it is necessary if you correctly push your controller using the navigation controller
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!
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).
I'm using a UINavigationController and I have a side menu in it. The problem is that when I want to push a UIViewController in the NavigationController from the side view it doesn't work. To do it, is use that code:
[self.slidingViewController resetTopView];
CDRecentChats* recentchats = [[CDRecentChats alloc]init];
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"conversation"];
[recentchats.navigationController pushViewController:controller animated:YES];
As you can see, I first close de side menu and then call the NavigationController to push a new ViewController. Using that code, the only thing that happens is that the menu is closed, but the NavigationController doesnnt push any ViewController. what can I do?
popToViewController means to go back to one that has already been made part of the navigation controller's stack. If you're trying to show a new one, use pushViewController.