I am trying to push a view controller to a navigation controller, but nothing happens.
I have the following code in my appDelegate (which works fine it seems):
ViewController1* VC1 = [[ViewController1 alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:VC1];
self.window.rootViewController = navController;
And the following code in VC1:
ViewController2 *VC2 = [[ViewController2 alloc]init];
[self.navigationController pushViewController:VC2 animated:YES];
VC2 gets initialised but isn't pushed to the navigation controller and therefor never presented. I have tried looking for answers for a while now but without success. What am I missing?
Thanks in advance!
Turns out the problem was that another navigation controller was active and had to be dismissed. The code posted was correct and all but I had totally missed another navigation controller.
Related
I get a EXC_BAD_ACCESS error message in my AppDelegate.m program when I attempt to goback to the previous view controller by popping the current view controller off the stack. The error obviously means that the viewcontroller is not in the stack.
My code for initializing my first view in my AppDelegate.m program is as follows:
CEMMainViewController *mc = [[CEMMainViewController alloc]
init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mc];
self.window.rootViewController = navController;
When I want to bring up a new view controller I do the following:
CEMUpdateBurialViewController *oc = [[CEMUpdateBurialViewController alloc] init];
[self.navigationController pushViewController:oc animated:YES];
When I want to return to the previous view I do the following which causes the EXEC_BAD_ACCESS error. So why isn't the previous view in the stack? I just need to know what I am doing wrong.
UINavigationController *navigationController = self.navigationController;
[navigationController popViewControllerAnimated:YES];
Check your view controller hierarchy with the following code:
NSLog(#"%#",self.navigationController.viewControllers);
And try this method:
[self.navigationController popToRootViewControllerAnimated:YES];
If I present a controller with a view controller, is it part of the self.navigationcontroller stack?
In essence:
UBSLoginViewController* loginView = [[UBSLoginViewController alloc] initWithNibName:LOGINVIEW bundle:nil];
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:loginView];
navigation.navigationBarHidden = YES;
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
[loginView presentViewController:[[UBSLoadingViewController alloc] initWithNibName:LOADINGVIEW bundle:nil] animated:YES completion:nil];
Is the loading view part of the navigation stack? Essentially, I want to present a modal view that will not be part of the root navigation stack.
If I present a controller with a view controller, is it part of the
self.navigationcontroller stack?
No.
You need to push the view controller onto your UINavigationController in order for it to be on the navigation controller's stack. Right now you are modally presenting on a view controller which is an entirely different concept.
Pushing onto a navigation controller looks something like this.
[self.navigationController pushViewController:loadingViewController animated:YES];
I'm running into an issue where an error is only raised periodically. In fact it seems almost random. Here's what happens, I'm launching a modal view controller with the following code:
- (void)createMessageClicked
{
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Channel" bundle:nil];
UINavigationController *nav = [sb instantiateViewControllerWithIdentifier:#"HIComposeMessageNavController"];
HIComposeMessageViewController *vc = [[nav viewControllers]objectAtIndex:0];
vc.channel = [self.channels objectAtIndex:0];
[self.navigationController presentViewController:nav animated:YES completion:nil];
}
Most of the time, this works fine. However once in a while the app crashes and raises the error "Application tried to present modally an active controller <UINavigationController>. Any ideas what I'm doing wrong here?
Try instantiating the controller that is embedded in your navigation controller in your storyboard, then create a new instance of a generic navigation controller:
HICompseController *controller = [sb instantiateViewController:
HIComposeMessageViewController];
UINavigationController *nav = [[UINavigationController alloc]
initWithRootViewController:controller];
[self presentViewController:nav animated:YES completion:nil];
I would suggest setting an ivar for your UINavigationController, because every time the action is triggered you are creating a whole new navigation controller and present it modally.
I suspect it occurs more often when the time in between click actions are close, hence after the modal controller has dismissed but did not get enough time for navigation controller to be deallocated before a new one that is instantiated from the same class is created and presented again modally. By using the same navigation controller, you can at least be sure that it is dismissed before it is presented again via that method.
Try to create an ivar for the navigation controller and reuse that every time in that method.
This worked for me:
if let presented = self.presentedViewController,
!presented.isBeingPresented {
self.present(navController, animated: true, completion: nil)
}
I have a problem trying to access a navigation controller of the view controller from it, always returns as nill to me, though it is shown within the navigation controller.
Here is what I have (I have a split view controller, that is presented as tab controller for master and viewcontroller (inside navigation controller) as detail):
FirstDetailViewController *fdvc = [[FirstDetailViewController alloc] initWithNibName:#"FirstDetailViewController" bundle:nil];
UINavigationController *fdvcNav = [[UINavigationController alloc] initWithRootViewController:fdvc];
NSArray *ipadVCs = [[NSArray alloc] initWithObjects:tabController, fdvcNav, nil];
UISplitViewController *splitvc = [[UISplitViewController alloc] initWithNibName:nil bundle:nil];
[splitvc setViewControllers:ipadVCs];
[[splitvc view] setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"splitViewControllerBG"]]];
[splitvc setDelegate:fdvc];
[[self window] setRootViewController:splitvc];
[[self window] makeKeyAndVisible];
But when I'm trying to access a navigation controller from the fdvc view controller in ViewDidLoad with [self navigationController] it gives me (Null) always.
Thanks!
I fixed it. Turned out, that I had to move my code from ViewDidLoad method to ViewDidAppear and it worked fine.
viewDidLoad is getting called before the navigationController property has been updated, that was my mistake.
How do I add the back button to a navigation bar? I know there are some related questions but none of them helped. I'm not using storyboard nor did I start with the Master Detail template. Is there a setting to do this? or do you add it by code? if so what code do I need? Any help is appreciated! THANKS!
The back button will appear by default if you use a navigationController correctly. The ViewControllers should be this
NavigationController > FirstViewController > SecondViewController
You will need to create navigationController and instantiate with firstVC as the root. From firstVC you can push secondVC and the back button will be there.
The following placed into appDelegate application didFinishLaunchingWithOptions: will load firstVC initially. Place this after you initialize the window...
UIViewController *firstVC = [[UIViewController alloc] initWithNibName:#"firstVC" bundle:nil];
// any setupup of firstVC
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:firstVC];
[self.window setRootViewController:navCon];
Then in your firstVC class if you want to push secondVC
in firstVC.m:
UIViewController *secondVC = [[UIViewController alloc] init];
[self.navigationController pushViewController:secondVC animated:YES];
You don't need to explicitly add a back button. The button will be added automatically when you push controllers into a UINavigationController. That is, a call as:
[navigator pushViewController: controller animated: ...];
creates a back button.