Navigation Item not appearing on View Controller - iphone

I apologize I am new to iphone programming.
I have created a Master-Detail Iphone application (so Navigation Controller came with the project). I segue to a new view controller I created through a UIBarButtonItem on the masterviewcontroller. However unlike the detailviewcontroller (that came with the project) I can not seem to get the navigationitem (or navigationbar?) to display on the view even though it appears in the scene list of my storyboard.
Heres some code and a screenshot:
In my masterviewcontroller.m viewdidload() function
UIBarButtonItem *settingsButton = [[UIBarButtonItem alloc] initWithTitle:#"Settings" style:normal target:self action:#selector(goToSettings:)];
self.navigationItem.leftBarButtonItem = settingsButton;
in my masterviewcontroller.m
- (IBAction)goToSettings:(id)sender{
[self performSegueWithIdentifier:#"SettingsSegue" sender:self];
}
I tried adding a title to the navigationitem during the viewDidLoad function of the new viewcontroller.m class i created (mentioned in this Link but it didn't work)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationItem.title = #"Settings";
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}
But it still shows up in my storyboard ( it shows up in the list under the scene but not in the display of the view)
So my question is why is it now showing up and how do I get it to? I want a back button like my detail view controller that came with the master-detail project.
EDIT#1
I have added a check for whether navigation controller is nil and it is not nil (the if statement is never entered) I also tried changing the navigation item to back and removing and none has worked.
if(self.navigationItem == nil)
{
[ self.navigationItem init];
}
self.navigationItem.title = #"Settings";
self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;
Now that I have enough reputation to show an image I can show that the navigation item shows up in the list but doesnt show up on the view

The Navigation item did not show up because of the "style" of my segue.
The segue that moved the scene from the master view controller to the settings view controller was set to 'modal'. It has to be set to 'push'. This is done from the storyboard on the utilities pane

You have to change your Segue Style by doing this:
Select the Segue in your Storyboard;
Go to the Attributes inspector (on the right pane tabs);
Change the Style attribute to Push.
It will make the screen roll from right to left and the Navigation bar will appear sliding.
With Modal, the screen come from bottom to the top of the screen and it will not let the Navigation bar appears.

The problem in my case was that the Navigation controller wasn't the "initial View Controller"
So I had to do this

You have verified that your navigation controller listed in the viewDidLoad method is not nil?
Assuming that you do correctly have a self.navigationItem that is non-nil, it appears that you are incorrectly setting your self.navigationItem.leftBarButtonItem to an editButtonItem, instead try removing this all together!
If removing it does not solve the problem try:
self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

Please check if your view controller is the root view controller of the navigation controller. You cant directly present a view controller as a modal view controller. You have to make your view controller as the root view controller of a navigation controller and then present your navigation controller as the modal view controller.
// Create the root view controller for the navigation controller
// The new view controller configures a Cancel and Done button for the
// navigation bar.
YourViewController *addController = [[YourViewController alloc]
init];
// Configure the YourViewController.
// Create the navigation controller and present it.
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:addController];
[self presentViewController:navigationController animated:YES completion: nil];

You need to have a Navigation Controller and a View Controller.
"The navigation controller manages the navigation bar at the top of the interface and an optional toolbar at the bottom of the interface. The navigation bar is always present and is managed by the navigation controller itself, which updates the navigation bar using the content provided by its child view controllers. When the isToolbarHidden property is false, the navigation controller similarly updates the toolbar with contents provided by the topmost view controller."
https://developer.apple.com/documentation/uikit/uinavigationcontroller

The Navigation Item also appears in the View Controller Scene you can look for it there and edit it too

Related

UINavigationController navigationbar visibility set not works

I'm trying to add some navigation controller in my app, it's sth likes:
in my index page view controller, I try to initialize the navigation controller like this:
-(void)viewDidLoad{
...
//allocate a navigation controller.
myNavigationController = [[UINavigationController alloc]init];
myNavigationController.delegate = self;
myNavigationController.navigationBar.hidden = YES;
[self.view addSubview:myNavigationController.view];
[myNavigationController pushViewController:tabViewController animated:YES];
[self presentModalViewController:myNavigationController animated:YES];
}
Here, index page view controller is the root view controller of my app, it's just a common UIViewController here.
[myNavigationController pushViewController:tabViewController animated:YES];
The tabViewController here I've pushed into the navigation controller is a custom tabview controller which makes use of a container view to hold the tab button and also holds an navigation controller for tab switching.
The problem here is:
myNavigationController.navigationBar.hidden = YES;
since I've make the navigation bar invisible, it doesn't show when my custom view controller shows, but when I'd like to switch to some other view controller with the navigation controller and I also want the navigation bar visible:
myNavigationController.navigationBar.hidden = NO;
MyViewController *toSwitchNC = [[MyViewController alloc]init];
[myNavigationController pushViewController:toSwitchNC animated:YES];
The navigation bar would never show any more. I've also tried to put:
self.navigationController.navigationBar.hidden = NO
in MyViewController's viewDidLoad, ViewDidAppear or even in the navigation controller's delegate method, it didn't show the navigation bar neither.
So what's wrong with it? Why I initialized the navigation bar to be invisible at first, it will never show again even I set the hidden flag to be false?
Okay, I've got this fixed by removing the navigation controller container in my index page view controller. This might be a stupid question, since apple've formally stated in the developer document that the navigation view controller should be place as root as possible in the view stack. Since IOS is a closed system, who knows WTH is going on under-beneath except Apple.

Modal View with Navigation Controller's Bar

When I try to present a modalViewController, it covers up my navigation controller's navigation bar. Any tips? Thanks.
UPDATE (with code):
ComposeText *compText = [[ComposeText alloc] initWithNibName:#"ComposeText" bundle:[NSBundle mainBundle]];
compNavController = [[UINavigationController alloc] initWithRootViewController:compText];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:compNavController action:#selector(compDoneTapped:)];
compNavController.navigationItem.rightBarButtonItem = doneButton;
[self presentModalViewController:compNavController animated:YES];
compText.title = #"Compose";
[doneButton release];
Everything seems to be in order, but the button is still not appearing on the navigation bar.
That's what it is supposed to do. If you want a navigation bar, present a new UINavigationController modally and set it's root view controller to your modalViewController.
The question you need to ask yourself is: "why do I want to show my navigationbar". If it is to give the user access to some buttons then it is the wrong reason. Modal view controllers are there to take full control of the screen and to not allow the user to manipulate anything else in the app until the controller is dismissed. If you don't want that do as Cyprian suggests and push a viewcontroller on your navigation stack.
If it is just a visual thing (logo ...) duplicate it in your modal view controller.
UINavigationController has it's own method to show another viewController.
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
It uses stack, to push new viewController so it can handle its navigation with buttons.

UITabBar Modal ViewContoller

I'm trying to present a TabBarController on top of another TabBarController. My application's MainWindow.xib looks like this:
Files Owner
First Responder
My App App Delegate
Window
TabBarContoller
+TabBar
+Nav Controller Subclass (a custom class)
+Navigation Bar
+Table View Contoller Subclass (custom class)
+Tab Bar Item
+Second View Controller (not yet hooked up)
I'm trying to display a xib file when an item is clicked in the TableView. This xib file has a TabBarController as it's main view, but when the view displays, the tab bar and navigation bar are both invisible. The code I'm using to display it is:
MyAppAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.customNavController presentModalViewController:customDetailEditViewController animated:YES];
If I use the code below to push the view controller onto the stack, I see the correct navigation bar, but the TabBar from the root view controller is shown instead of the one from the view which has been pushed.
[delegate.customNavController pushViewController:customDetailEditViewController animated:YES];
I even tried removing the TabBarController and manually implementing my own TabBar delegates but the same effect occurs (either no NavigationBar or TabBar, or the NavigationBar/TabBar from the root ViewController).
EDIT: I've uploaded the source to http://mi6.nu/tabcontroller.zip . I'd really appreciate it if someone with a bt more experience with iOS could take a look.
EDIT2: The closest I've come so far is presenting a modal view controller inside the first tabbar, so my view looks like this:
NavigationBar
[ ]
[ ]
[---View---]
[ ]
[ ]
TabBar from the pushed view
TabBar from the root view
To achieve this, I'm using:
UITabBarController *tabBarController = [[UITabBarController alloc] init];
UIViewController *directionsView = [[UIViewController alloc] init];
txtDirections = [[UITextView alloc]initWithFrame:CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height)];
[directionsView.view addSubview:txtDirections];
IconPickerViewController *iconPicker = [[IconPickerViewController alloc]init];
tabBarController.viewControllers = [NSArray arrayWithObjects:recipeDetailEditViewController,directionsView,iconPicker, nil];
[directionsView release];
[iconPicker release];
MyAppAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.rootNavController presentModalViewController:recipeDetailEditViewController animated:YES];
This just complicates everything though, since a) It's not ideal as I have two tabbars and b) all controls (all of the editing controls) need to be in the TableViewController so their values can be loaded/saved to edit items. It would be much easier if the pushed view could handle loading/saving and appear on top of the root tabs.
Surely this must be possible?
This was an absolute nightmare, but I eventually got it working by presenting the view modally from the TableViewController when the add button is clicked:
[delegate.rootController presentModalViewController:recipeDetailEditViewController animated:YES];
delegate.rootController is the root TabBarController
The XIB file I'm presenting does not have a TabBarController, but rather a UIView, a Navigation bar and a TabBar. This appears to work when presented modally from inside a NavigationController.
Why are you putting everything in your main.xib?
Try moving the second tab bar out of the main window xib and instead put it inside the customDetailEditViewController.

Using non-modalview delegation for iPhone

Okay, I understand how to work delegation in a modal view to send a message to the parentviewcontroller but what if I wanted to do that with 2 views that dont have that parent-child relationship?
I have a navigation controller that flips over a modal view and then that modal view pushes a new view controller. How do I let that pushed view controller talk to the navigation controller. The modal view code that I have been using places this in the parent:
-(IBAction)pressedUnitAddy {
UnitAddyView *unitVC = [[UnitAddyView alloc] init];
unitVC.delegate = self;
UINavigationController* theNavController = [[UINavigationController alloc]initWithRootViewController:unitVC];
theNavController.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self presentModalViewController:theNavController animated:YES];
[unitVC release];
[theNavController release];
}
-(void)didDismissUnitAddyView {
[self dismissModalViewControllerAnimated:YES];
}
....and then I call the didDismissUnitAddyView from the UnitAddyView. Now, I am not trying to dismiss any views with what I am trying to do but I do want that pushed view controller to be able to speak to the navigation controller. How would I do that?
View controllers have a property, navigationController, that is nil if they're not pushed onto a navigation controller and is a pointer to the navigation if they are. Does that answer your question?
All I was trying to do was to reload the data on the nav controller screen. The UIViewController and the nav controller we not directly connected - they were separated through a modalview. All I did, and I should have thought of this earlier, was set the modal view's delegate to the nav controller and to call a method to reload the nav controller when the modal view is dismissed.

strange behavior when changing UINavigationController backItem title

I'm changing the back button item title in the viewDidAppear of a controller in the following way:
self.navigationController.navigationBar.backItem.title = #"Previous";
It changes the tittle properly, but the I'm having a strange behaviour. When I select the "previous" button, it changes the tittle of the controller that is up in the stack (i.e the parent controller now has the title "Previous".
Do you now why this happened?
When you're using a navigation controller, calling [self setTitle:#"Title"]; inside of any view controller in the stack will set the navigation bar title. This is also the title used by default for the back button when you've pushed a new view controller. Apparently, from what you are experiencing, explicitly setting the title of the backItem, also sets it for the navigation bar title for the previous view controller overriding whatever what specified in the call to -setTitle in the view controller.
You will probably be better off just managing the title from within the view controllers in your navigation stack. When you go to push a new view controller, do this:
[self setTitle:#"Previous"];
NextViewController *controller = [[NextViewController alloc] init];
[[self navigationController] pushViewController:controller animated:YES];
[controller release], controller = nil;
Now, when the next view controller displays, the back button with say "Previous". Now, you just need to change it back to whatever its real title should be in -viewWillAppear:
- (void)viewWillAppear:(BOOL)animated;
{
[self setTitle:#"Real Title"];
[super viewWillAppear:animated];
}
It may feel a little hacky, but it's better than trying to override the navigation bar functionality. Wrestling with the nav bar/nav controller stack can prove very frustrating.
Best regards.