I have a Navigation application that has a view controller in it.. I am now trying to load another NavigationController into that ViewController however I am experiencing problems..
I am trying to do it programmatically because I am not sure how to do it in InterfaceBuilder however the new navigation controller displayes weird.. like it thinks there is a infobar above it.. so has a white gap..
As you can see here.
This is all I am doing to get this ^ current look....
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
UINavigationController *newNav = [[UINavigationController alloc] init];
[self.view addSubview:newNav.view];
newNav.navigationItem.title=#"Navigation Controller Example";
}
Any help would be greatly appreciated.
As you say,you just have an Navi-based App, so if you want to add another NavigationController in your application ,you should hide the new NavigationController's bar .Following is the code.
[newNav setNavigationBarHidden:YES animated:YES];
Related
I have added a navigation controller inside a viewcontroller thats inside another navigation controller... lol
well anyway because of this structure I have an issue with any views I push to the "sub"navigation controller.. because its only fitting inside the grame of the "parent" navigation controller its pushing the pushed views contents down by about 20/40pxl...
I was wondering how I get stop this from happening.. here are two pictures showing you what is happening.
where the label is clearly centered in Interface builder
This is the code I have so far for this stuff.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
// Init the (sub)navigationController
otherNav = [[UINavigationController alloc] init];
// Add this (sub)NavController to the current viewcontroller (which is inside the (parent)navcontroller)
[self.view addSubview:otherNav.view];
// Hide the (sub)NavControllerbar
otherNav.navigationBar.hidden = YES;
// Load a detial view into the (sub)NavController
DetailViewController *detailView = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
[otherNav pushViewController:detailView animated:NO];
}
The otherNav is also set up in the .h file for global access in this view.
When the "super" NavigationBar is visible, the self.view.frame.height is:
480-20-44 (actualViewheight-statusbarheight-navigationBarheight).
There are 2 solutions for your problem.
1. For simplicity I would say, if your only problem is to make it centralized.
[self.view addSubview:otherNav.view];
[otherNav.view setCenter:self.view.center];
This will make your label center alligned.
2.Though, if you are using interface builder;
select the xib file.
select the view.
open Utilities.
set the Top bar as Navigation bar.
then the things you will align you will get as it is on device/simulator or what ever you are testing on.
I have a button when it pressed, I want it to take me to another view (the "news" view). Within the news view, I want there to be a navigation bar with a back button. I have a navigationcontroller setup throughout my app but I can't seem to get this to work when this button is pressed. It takes me to the view I want but there is no navigation bar and no back button. This is my code that is implemented when the button is pressed.
If anybody know what I am doing wrong, it would be much appreciated.
Thanks
-(IBAction)news
{
newsViewController *view1 = [[newsViewController alloc] initWithNibName:#"newsViewController" bundle:nil];
view1.title=#"news";
[self.navigationController pushViewController:view1 animated:YES];
}
I am not in my mac, so I can not test code, but if it is working and the only issue you got is not show the bar, what you need to is set the bar to be visible:
From apple docs:
The navigation toolbar is hidden by default but you can show it for
your navigation interface by calling the setToolbarHidden:animated:
method of your navigation controller object. If not all of your view
controllers support toolbar items, your delegate object can call this
method to toggle the visibility of the toolbar during subsequent push
and pop operations.
Something like that is supposed to work:
-(IBAction)news {
newsViewController *view1 = [[newsViewController alloc] initWithNibName: #"newsViewController" bundle:nil];
view1.title=#"news";
[self.navigationController pushViewController:view1 animated:YES];
//Add this line!
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
I hope it can help you.
write the below code in page where you want to show navigation controller
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = NO;
}
I have a ViewBased App. I added a UITableView on one of the UIViewControllers. It shows the data and I implemented all the delegate methods etc. My problem is when I want to show the detailView it just doesn't happen. My code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detailViewController =[[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
NSLog(#"DidSelectRowAtIndexPath");
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
I see that I need a navigationController but I don't have one and I was unsucessful trying to add one programatically. I don't have one in my appDelegate either, so my question is do I need to add one to show the detail view? If yes, please give me a code sample how to do that.
If not, what other way is there?
I am new to iOS so I am a bit lost here.
Please help!
To add a navigation controller programmatically just for this detail view, you need to something like this:
UINavigationController * controller = [[UINavigationController alloc] initWithRootViewController:detailViewController];
[[detailViewController] release];
[self presentModalViewController: controller animated: YES];
If you want to use pushViewController, you need to already have a navigation controller surrounding the view you're starting with.
You need to add the Navigation Controller FIRST, then your master table becomes the root view controller of the nav controller, then when you tap a row in the table, you push another view controller onto the nav stack.
How does your master table get into the app in the first place? If you're using a nib, it's super easy to just change out the view controller for a nav controller with the old view controller added as a child of the nav controller.
You can create one programmatically by working within your app delegate's application:didFinishLaunchingWithOptions: method like so:
UITableViewController *tableViewController = [[[WhateverYourSubclassVCIsCalled alloc] init] autorelease];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
window.rootViewController = navController;
[window makeKeyAndVisible];
I am showing a modal view which is a UITableViewController class. For some reason it won't show the navigation bar when I show it. Here is my code:
SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped];
detailViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
detailViewController.navigationController.navigationBarHidden = NO;
[self.navigationController presentModalViewController:detailViewController animated:YES];
detailViewController = nil;
[detailViewController release];
I thought it was shown by default? If it helps, I am calling this from another class that is also a UITableViewController managed by a UINavigationController. Ideas?
When you present a modal view controller it does not use any existing navigation controllers or navigation bars. If all you want is to display a navigation bar, you need to add the navigation bar as a subview of your modal view and present it as you're doing.
If you want to present a modal view controller with navigation functionality, you need to present a modal navigation controller containing your detail view controller instead, like so:
SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
[detailViewController release];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:navController animated:YES];
[navController release];
Your modal controller will manage its own navigation stack.
Here is one way to display navigation bar for those who are using storyboards, suggested by Apple's Tutorial on Storyboard.
Because a modal view controller doesn’t get added to the navigation stack, it doesn’t get a navigation bar from the table view controller’s navigation controller. To give the view controller a navigation bar when presented modally, embed it in its own navigation controller.
In the outline view, select View Controller.
With the view controller selected, choose Editor > Embed In > Navigation Controller.
On iOS 7 and you just want a navigation bar on your modal view controller to show a title and some buttons? Try this magic in your UITableViewController:
// in the .h
#property (strong) UINavigationBar* navigationBar;
//in the .m
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = #"Awesome";
self.navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectZero];
[self.view addSubview:_navigationBar];
[self.navigationBar pushNavigationItem:self.navigationItem animated:NO];
}
-(void)layoutNavigationBar{
self.navigationBar.frame = CGRectMake(0, self.tableView.contentOffset.y, self.tableView.frame.size.width, self.topLayoutGuide.length + 44);
self.tableView.contentInset = UIEdgeInsetsMake(self.navigationBar.frame.size.height, 0, 0, 0);
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
//no need to call super
[self layoutNavigationBar];
}
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[self layoutNavigationBar];
}
I want to share how the accepted solution can be used in projects with storyboards:
The simple approach is to put in a storyboard blank navigation controller before the VC which is to be presented modally, so the relations look like:
(Presenter VC) -> presents modally -> (navigation controller having a controller to be presented as its root).
We've tried this approach for a while and noticed that our storyboards become "polluted" by a large number of such intermediate navigation controllers when each! of them is used exclusively for one! presentation of some other controller, that we want to be presented modally with navigation bar.
Our current solution is to encapsulate the code from accepted answer to a custom segue:
#import "ModalPresentationWithNavigationBarSegue.h"
#implementation ModalPresentationWithNavigationBarSegue
- (void)perform {
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.destinationViewController];
[self.sourceViewController presentViewController:navigationController animated:YES completion:nil];
}
#end
Having this segue in our project we do not create intermediate navigation controllers in our storyboards anymore, we just use this ModalPresentationWithNavigationBarSegue like:
Presenter VC --> Presentee VC
I hope that this answer will be helpful to people who like to avoid unnecessary duplication in their apps storyboards.
I just wanted to add something to what #Scott said. His answer is definitely the easiest and most accepted way of doing it now with Storyboards, iOS 7 and 8... (and soon, 9).
Definitely adding a view controller to the Storyboard and Embedding it as described by #Scott is the right way to go.
Then, just add the segue by control-dragging from the source view controller to the target (the one you want to show modally), select "Present Modally" when the little view appears with the choices for the type of segue. Probably good to give it a name too (in the example below I use "presentMyModalViewController").
One thing that I needed that was missing is #Scott's case is when you want to actually pass on some data to that modally-presented view controller that is embedded in the navigation controller.
If you grab the segue.destinationViewController, it will be a UINavigationController, not the controller you embedded in the UINavigationController.
So, to get at the embedded view controller inside the navigation controller, here's what I did:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"presentMyModalViewController"]) {
// This could be collapsed, but it's a little easier to see
// what's going on written out this way.
// First get the destination view controller, which will be a UINavigationController
UINavigationController *nvc = (UINavigationController *)segue.destinationViewController;
// To get the view controller we're interested in, grab the navigation controller's "topViewController" property
MyModalViewController *vc = (EmailReceiptViewController *)[nvc topViewController];
// Now that we have the reference to our view controller, we can set its properties here:
vc.myAwesomeProperty = #"awesome!";
}
}
Hope this helps!
If you only need a NavigationBar, you can add an instance of UINavigationBar and assign BarItems to it.
I'm building an application based on the Utility template from Xcode, to which I have added some more views. My application structure would be as follows:
MainView (the app menu)
Flip-side view (a calculator)
UINavigationController
Settings view
viewDiDLoad: UITabBarController
- Tab1 view (options)
- Tab2 view (information text)
I can navigate correctly from my MainView to my Flip-side view, which is also the root view of the Navigation Controller. From my Flip-side view, I push a second view of my Navigation Controller (Settings view) that is configured to show an UITabBarController, with two tabs, as soon as it loads (with viewDidLoad).
If I remove the UITabBarController, I can return with no problems to my Flip-side view using "popViewController" from my Settings view. The problem comes if I load the UITabBarController in viewDiDLoad in my Settings view... the tabs work perfectly, but I'm not able to return to my Flip-side view (root view of the Navigation Controller) anymore.
I CAN return if I use the Navigation Bar of the Navigation Controller, but I want to configure my own buttons and have the Navigation Bar hidden.
So far I've tried the following methods:
[self.navigationController popViewControllerAnimated:YES];
[self.navigationController popToRootViewControllerAnimated:YES];
[self.navigationController popToViewController:FlipSideViewController animated:YES];
But they don't seem to work. The first two just do nothing (the screen remains as it was), and the third one does not recognize the "FlipsideViewController" (maybe because it's a delegate of the MainViewController?).
Is there a way to check what is exactly doing the "back" button of the Navigation Bar if I activate it?
Should I be using delegates?
Can I call a popViewController method in my Settings view from any of the two Tab views?
This is my Flip-side view:
- (IBAction)showSettingsView {
SettingsViewController *controller = [[SettingsViewController alloc] initWithNibName:#"SettingsView" bundle:nil];
controller.title = #"Settings";
[self.navigationController pushViewController:controller animated:YES];
[controller release];
}
This is my Settings view:
- (void)viewDidLoad {
[super viewDidLoad];
tabBarController = [[UITabBarController alloc] init];
Tab1ViewController* vc1 = [[Tab1ViewController alloc] init];
Tab2ViewController* vc2 = [[Tab2ViewController alloc] init];
NSArray* controllers = [NSArray arrayWithObjects:vc1, vc2, nil];
tabBarController.viewControllers = controllers;
[self.view addSubview:tabBarController.view];
}
And the method to return in one of the Tab views:
- (IBAction)backFromTab1View {
[self.navigationController popToViewController:FlipSideViewController animated:YES];
}
Thanks very much and sorry if the question is too basic!
I actually solved the problem creating my own UINavigationBar in the Settings view and using:
[self.view insertSubview:tabBarController.view belowSubview:myNavigationBar];
That inserts the rest of the view below the Navigation Bar and I still can use it to configure a button which pops the view and return to the previous screen.
It took me a while to realise the differences between "addSubview" and "inserSubview + belowSubview". Sorry about that!