I have 3 VC(view controller) (VC1, VC2, VC3).
At VC1, I used the code:
self.navViewController = [[UINavigationController alloc] initWithRootViewController:viewController];
self.navViewController.view.frame = CGRectMake(self.view.frame.size.width - viewController.view.frame.size.width,
viewController.view.frame.origin.y,
viewController.view.frame.size.width,
viewController.view.frame.size.height);
[self.navigationController addChildViewController:self.navViewController];
[self.navigationController.view addSubview:self.navViewController.view];
[self.navViewController didMoveToParentViewController:self.navigationController];
The VC2 is showing, and then at VC2 I used the code to push navigation controller to VC3
VC3 *vc3 = [[VC3 alloc] initWithNibName:#"VC3" bundle:nil];
[vc3.view updateConstraintsIfNeeded];
[self.navigationController pushViewController:vc3 animated:YES];
Currently, when I'm adding snippet code [vc3.view updateConstraintsIfNeeded];. I saw navigation of changed and content view does not change and show. It just shows a content view of VC2.
In my project, I'm using auto layout. I tried remove auto layout on my project it works well. When I added auto layout it works wrong.
It just occurs on iOS 7, iOS 8 work well.
Please, help me to resolve the bug. Many thanks!
The problem is you are displaying your VC2 on top of the pushed view controller. What is the reason to have one view controller as a child of a navigation controller? Instead, have a common ancestor of both VC2 and the navigation controller, or put your VC2 somewhere else in the view hierarchy, not on top of of the navigation controller's view, which holds the entire navigation controller (including contained controllers in the push stack) view hierarchy.
Related
I added a Navigation Controller to my storyboard and it appears like so:
Now in the table view controller, I gave the TableViewController a storyboard id and class to a TableViewController Controller
When I run my app, I don't see the Navigation Bar at the top. This has been extremely frustrating and can't find a solution anywhere. PLEASE HELP
To get to the scene, someone clicks a button and this code runs and it goes to my Table View Controller:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
LHFileBrowser *LHFileBrowser = [storyBoard instantiateViewControllerWithIdentifier:#"FileBrowser"];
[self.navigationController pushViewController:LHFileBrowser animated:YES];
[self presentViewController:LHFileBrowser animated:YES completion:nil];
The error is in your code.
If you want to (modally) present a view controller when the user presses a button, you need to present the navigation controller (which will contain the table view controller), not the table view controller itself.
Right now, you're presenting the view controller, which won't show it being embedded in a navigation controller.
Also, you're mixing up two different approaches, by trying to push a view controller onto a navigation controller stack, and also presenting the view controller.
Code Sample:
Here's what you apparently mean to do:
UIStoryboard *storyboard = self.storyboard;
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:#"MyNavigationControllerID"];
LHFileBrowser *rootViewController = [navigationController topViewController];
// Configure your LHFileBrowser view controller here.
rootViewController.someProperty = ...;
// Modally present the embedded view controller
[self presentViewController:navigationController animated:YES completion:nil];
If you want to change the presentation or transition style, you can set those details in your storyboard.
You didn't explain why you had to programmatically add buttons, but Storyboard segues would have instantiated and presented an embedded view controller for you, without you having to have done it in code.
The more you can do in Storyboard, the less code you have to maintain, support, and update, and the more likely your app will still work properly when a new SDK is released.
Update:
The better way to do this is to let Storyboard do it for you, by adding a segue from the button to the navigation controller that you want to present.
I'm new to xcode ios 7.
I've struggling a lot with navigation controls building app for iPhone ios7.
I don't want to use storyboard. I prefer to do it programmatically.
What i am trying to do.
I know how to create NavigationBar & Navigation Toolbar via AppDelegate.m
But if it's possible i don't want to do it, because let's assume i want in FirstViewController to show just simple button "Go to Second View Controller" (No Navigation Bar or Toolbar here).
And now in SecondViewController i want to create Navigation Toolbar (bottom) with 4 different tabs linking to ViewControllers!
But the trick is, i want to maintain different Navigation Bar (top) for every ViewController (as you can see in this screenshot).
Here is my Xcode Project File
And here is screenshot form Fancy app showing what i am trying to achieve.
Thanks a lot in advance!
Just to give you an idea, When you tap the button on your first view controller, you can create a UINavigationController and set your second view controller as its root view controller. This way, your first view controller remains no nav bar view and the second view controller holds a Navigation controller. Try something like below:
-(IBAction)goToSecondVC:(id)sender // An action for the button in your first VC
{
SecondViewController *secondVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil]; //Init with second view controller
UINavigationController *secondNavVC = [[UINavigationController alloc] initWithRootViewController:secondVC]; // create a navigation controller and set the root as your second view controller
[self presentViewController:secondNavVC animated:YES completion:nil]; // and then present it with anim or no anim..
}
I have a tab bar controller with 4 tabs and each tab is their own UINavigationController, which is how you're supposed to nest tab bar and navigation controller's together. The initial tab is a TableViewController and works/appears the way that it should. From the tableVC I can push standard view controller's onto the navigation controller with:
[self.navigationController pushViewController:VC animated:YES];
and it works properly.
If I attempt to push another TableViewController onto the navigation with the same method it works the same way, but the initial tab bar does not get pushed off screen like it should, it just stays in place.
Why would the tab bar stay on screen even though I am pushing a new VC onto the navigation?
I have tested with multiple instances of different TableVC's and it only happens with a table view controller.
Here is the code I'm using:
- (void)pushTableVC
{
TestTableVC *tableVC = [[TestTableVC alloc] init];
[self.navigationController pushViewController:tableVC animated:YES];
}
This will push the new table view onto the stack, but the tab bar from the parent VC stays in place and does not get pushed off screen like it should.
You should call the method setHidesBottomBarWhenPushed: on the view controller you are pushing to correctly hide the tab bar.
UIViewController *viewController = [[UIViewController alloc] init];
[viewController setHidesBottomBarWhenPushed:YES];
[[self navigationController] pushViewController:viewController animated:YES];
When you use a UITabBarController, the tab bar always stays on screen, even as you push additional view controllers onto an embedded UINavigationController. You will see this in any app that has a UITabBarController implemented, unless they implement custom behavior to change this.
The UINavigationController contains everything above the UITabBar, but does not contain the UITabBar itself, so it would not be able to push it offscreen.
I have setup a UINavigation controller that uses the AppDelegate as the main point of contact.
I have different methods which run such as presentHomeViewController, presentLoginViewController, which push the different view controllers to the Navigation Controller.
App Delegate - didFinishLaunching
welcomeViewController = [[MyWelcomeViewController alloc] initWithNibName:#"MyWelcomeViewController" bundle:nil];
navController = [[UINavigationController alloc] initWithRootViewController:welcomeViewController];
navController.navigationBarHidden = YES;
self.revealSideViewController = [[PPRevealSideViewController alloc] initWithRootViewController:navController];
[self.revealSideViewController setDirectionsToShowBounce:PPRevealSideDirectionNone];
[self.revealSideViewController setPanInteractionsWhenClosed:PPRevealSideInteractionContentView | PPRevealSideInteractionNavigationBar];
self.window.rootViewController = self.revealSideViewController;
Is this the correct process for this?
- (void)presentHomeViewController {
// We start by dismissing the ModalViewConrtoller which is LoginViewController from the welcomeview
[self.welcomeViewController dismissModalViewControllerAnimated:YES];
// Check if the home view controller already exists if not create one
if (!self.homeViewController) {
NSLog(#"presentHomeViewController- Creating the Home View controller");
homeViewController = [[MyHomeViewController alloc] initWithNibName:#"MyHomeViewController" bundle:nil];
}
// Push the homeViewController onto the navController
NSLog(#"presentHomeViewController");
self.navController.navigationBarHidden = NO;
[self.navController setTitle:#"Home"];
[self.navController pushViewController:homeViewController animated:NO];
If I then add the following to a different class :
[self.navigationController pushViewController:accountViewController animated:NO];
No view is pushed to the stack, should I control all the movement within the AppDelegate as I have been doing, or is there betters way to approach this?
EDIT
Thanks for posting your code. So, to address your final question first, I don't recommend controlling your navigation stack from the app delegate. You should be controlling the stack from the view controllers that are the children of the navigation controller.
To that point, remember the hierarchy of view controllers: UINavigationController inherits from UIViewController, and UIViewController has properties defined for all the things you'd see in a navigation layout such navigation items and title. More importantly, it also has properties for its parent view controllers, the view controller that presented it, and its navigation controller. So, considering the hierarchy, your app delegate should only instantiate the navigation controller's root VC and the nav controller itself, and then subsequently set the nav controller's root VC.
From there, you should be pushing and popping other VCs from the VCs themselves. Remember, every VC has a property that's automatically set to point at the navigation controller it's a part of. That's why [self.navigationController pushViewController:] works. For instance, if I have a nav controller whose root VC is a UITableViewController, and tapping on one of the items in the table view pushed a new VC onto the stack, I would push that VC from the table VC and not from the nav controller class or the app delegate.
Sorry if that's confusing. Please let me know if that needs clarification and I'll give it my best. Otherwise, hopefully that gets you on the right track.
I am using a NavigationViewController to navigate between master view and detailed views. Now I want to be able to switch to a sibling detail view without first showing the master view and I have tried doing popViewController and pushViewController in the same method or popViewController in the detailed view and then pushViewController in mater's viewDidLoad after popViewController but it won't work - the view just ends up going back to the master view without switching to the detail. Any idea what to do?
The solution suggested here doesn't work as far as I can tell:
Switching Content Views Issue
I've never tried it, but this should work:
// create instance of new view controller
MyViewController *myViewController = [[MyViewController alloc] init];
// get current stack of viewControllers from navigation controller
NSMutableArray *viewControllers = [[self.navigationController viewControllers] mutableCopy];
// replace top view controller in stack
[viewControllers replaceObjectAtIndex:([viewControllers count] - 1) withObject:myViewController];
// set modified stack of view controllers in navigation controller
[self.navigationController setViewControllers:viewControllers animated:YES];
According to the docs, your app will transition to the new view controller with a push animation, and then when back button is clicked it it will be as if the view controller you pushed from was never there. (If you don't want the animation, use animated:NO)