Swift: navigationController returning nil - ios

On a UIViewController instantiated by a UITabBarController, when I run the following code,
let destination = self.storyboard?.instantiateViewControllerWithIdentifier("test")
self.navigationController!.pushViewController(destination!, animated: true)
navigationController return nil. How can I get navigationController instance to push a view controller?

As #Paulw11 said, what was missing was embed the UIViewController in a navigation controller. To do that, drag-and-drop a Navigation Controller to the Storyboard and CTRL + drag from that Navigation Controller to the UIViewController, chosing the relationship root view controller.

Your source UIViewController instance needs to be embedded in a UINavigationController in the storyboard scene in order to provide a navigation controller instance to push to.

https://stackoverflow.com/a/32959896/3810914
Exactly. If you did, the error would be resolved

Related

How to push a UIViewController on top of UINavigationController (instead of inside it)?

What I mean by this is that I have the following design of view controllers, basically in the view stack, with the app root view being on the bottom
UINavigationController (RootViewController -> SecondViewController)
UIViewController
AppRootViewController
I want to perform an action in my SecondViewController that is inside of the UINavigationController, and when I do that, I want to segue to a NewUIViewController, to basically result in the following view controller stack:
NewUIViewController
UINavigationController (RootViewController -> SecondViewController)
UIViewController
AppRootViewController
But what is happening is the following:
UINavigationController (RootViewController -> SecondViewController -> NewUIViewController)
UIViewController
AppRootViewController
So I'm wondering if there is any way to basically "push" a new view on top of the UINavigationController, instead of pushing it into the UINavigationController.
Right now I am doing a segue from the SecondViewController to the NewUIViewController, but perhaps I have to do the segue from the UINavigationController instead? I thought I had tried this and it did not work as expected though, which is why I am asking here for some guidance.
Thanks.
Select your segue then change "Style" to "Modal" instead of "Push". It will do the trick. But if you want to comeback to your current UINavigationController, from your new UIViewController, you must have a button to close that modal and comeback to your current UINavigationViewController.

UINavigationController Storyboard Hopping

I would like to know what code is required to traverse the storyboard from a UIViewController located at index N of a UINavigationController which is embedded in a UITabBarController, to a similarly embedded UIViewController.
I would also like all UIViewControllers to be popped in the source UINavigationController
Direct segues (as shown in red) do not fit my use case.
Swift please.
You can pop to the root view controller then change the selected index of the index of the tab bar controller then push whatever view controllers you need on the other navigation controller. For example:
let tabBarController = self.tabBarController;
let indexZeroNavController:UINavigationController = self.tabBarController?.viewControllers![0] as! UINavigationController
self.navigationController?.popToRootViewControllerAnimated(true)
tabBarController?.selectedIndex = 0
let newViewController = self.storyboard?.instantiateViewControllerWithIdentifier("New View Controller")
let otherNewViewController = self.storyboard?.instantiateViewControllerWithIdentifier("Other New View Controller")
indexZeroNavController.pushViewController(newViewController!, animated: true)
indexZeroNavController.pushViewController(otherNewViewController!, animated: true)
Beyowulf's approach used to be valid, but things have changed. In the viewController you wish to pop to, define an "unwind segue". example Once it's defined, you can drag from a button to "exit" and select that unwind segue.
The way unwind segues work has been completely reworked in xcode 7, so you don't have to worry too much about the view controller stack.

Show segue inexplicably changes to a modal segue when a container view controller is used

I don't know the exact cause of this but I am guessing it has something to do with a container view controller being used. I am actually using several containers, one is for a SWRevealViewController, which houses a generic UIViewController for its rearViewController and a UINavigationController for the frontViewController. The root view controller of this navigation controller is another container view controller, a MainViewController, which contains a UIPageViewController. Page view controller has 3 UITableViewControllers and when I try to navigate from those table view controllers to the relevant view controllers (via a segue), and I want it to be a push transition, it makes a modal transition so what gives?
It is something to do with hierarchy I guess, but it is kinda messed up with all these view controllers right now and I think I broke my brain at some point. I would really appreciate if someone who knows what is wrong can explain.
Thanks for the replies but I got it working without the use of segues and the storyboard, by pushing the view controller in tableView delegate manually, like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PlaceViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"placeViewController"];
vc.place = self.places[indexPath.row];
[self.navigationController pushViewController:vc animated:YES];
}
was stuck with the same problem and tried to solve for almost 2 days, and finally solved that..
View Hierarchy:
Container View
First Controller (direct child of container)
Second Controller (direct child of container)
Third Controller
Fourth Controller
Solution
added Navigation controller to First Controller
added Navigation Controller to Second Controller
and when want to display any controller instead of presenting the controller itself present the UINavigationController, this will solve the problem of not happening segue push animation...
sample code, hoping it will help:
import UIKit
class ViewController: UIViewController {
var loginViewNavigation : UINavigationController!
var singupViewNavigation : UINavigationController!
override func viewDidLoad() {
super.viewDidLoad()
var storyBoard = UIStoryboard(name: "User", bundle: nil)
loginViewNavigation = storyBoard.instantiateViewControllerWithIdentifier("LoginViewNavigation") as! UINavigationController
singupViewNavigation = storyBoard.instantiateViewControllerWithIdentifier("SignupViewNavigation") as! UINavigationController
self.addChildViewController(loginViewNavigation)
self.addChildViewController(singupViewNavigation)
self.view.addSubview(loginViewNavigation.view)
}
}
Point to observe is the use the UINavigationController of the controller you want to display instead of that ViewController

PresentViewController to a ViewController with a different NavigationController but on the same storyboard

I'm having trouble with a simple Xamarin Studio Storyboards concept. See screenshots below for visuals and see the downloadable source code here.
Let's say I have a NavigationController with MainViewController on it. This is visible in my storyboard. I want a button which, when pressed, brings up a new NavigationController with RedViewController. I also want RedViewController on the same storyboard as the MainViewController. In this project, I tried to do that but for some reason when I do a:
var myStoryboard = AppDelegate.Storyboard;
// Instatiating View Controller with Storyboard ID 'StuffViewController'
RedViewController = myStoryboard.InstantiateViewController ("RedViewController") as RedViewController;
RedViewController.ModalTransitionStyle = UIModalTransitionStyle.CoverVertical;
this.PresentViewController(RedViewController, true, null);
the RedViewController doesn't have it's Navigation controller with it. When presented RedViewController's Navigation Controller is null! What am I doing wrong there?
Now when I created a NavigationController & BlueViewController in a totally seperate storyboard it works fine. When I press the Blue Button it goes to the BlueViewController and correctly shows it's NavigationController. Why is this one working but the other one not? The only difference that I can see is that they are on separate Storyboards.
UIStoryboard storyBoard = UIStoryboard.FromName ("BlueStoryboard", null);
UIViewController controller = storyBoard.InstantiateInitialViewController () as UIViewController;
controller.ModalTransitionStyle = UIModalTransitionStyle.CoverVertical;
this.PresentViewController (controller, true, null);
ViewController that can present a new NavigationController & ViewController ViewController called "Red" with a navigation bar
When you instantiate your new view controller you need to instantiate the UINavigationController, not the RedViewController.
In the case of your 'blue' code you instantiate the initialViewController - which is the navigation controller that contains the Blue controller.
You want
RedViewNavigationController = myStoryboard.InstantiateViewController ("RedViewNavigationController") as UINavigationController;
where 'RedViewNavigationController' is the identifier for the navigation controller that the Red View Controller is embedded in.
If you want to present the red controller with its navigation controller, you should instantiate the navigation controller (which, in turn, will instantiate the red controller), and present it.

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).

Resources