strange behavior when changing UINavigationController backItem title - iphone

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.

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.

Navigation Item not appearing on View Controller

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

displaying navigation bar when switching to another view

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;
}

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.

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.