UINavigationItem BackBarButtonItem not replaced - iphone

I'm having a curious issue with backBarButtonItem. I want to replace its title in the entire application for "Back" and replacing the back button works in most of -viewDidLoad event but in other views it's not working and show the name of the previous view. Has someone has the same problem?
P.S. The way to replace the backBarButtonItem is the standard one instantiating an UIBarButtonItem and setting it to viewController.navigationIten.backBarButtonItem property.

The backBarButtonItem does not set the back button that is shown in the current view, it sets the back button that navigates to the current view, i.e. the back button in the next view.
This makes sense because the back button's title is usually the title of the previous view controller.
If you want to set the left button in the navigation bar directly, use self.navigationItem.leftBarButtonItem.

when you push the view from your current view at that time after allocate your next viewcontroller object ,just put bellow line
YourViewController *objView = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil];
self.navigationItem.title=#"Back";
[self.navigationController pushViewController:objView animated:YES];
your Next View will Appear with Back Button....
:)

Well, at last I've found the solution to this issue.
If you want that any backBarButtonItem of your application has the same title a good approach is to subclass UINavigationController and override - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated to replace the back button.
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
UIBarButtonItem *_backButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"BackButtonLabel", "")
style:UIBarButtonItemStyleDone
target:nil
action:nil];
viewController.navigationItem.backBarButtonItem = _backButton;
_backButton = nil;
[_backButton release];
[super pushViewController:viewController animated:animated];
}
By this way every back button in your application will have the same title.
I hope this will be helpful for anyone else.

Related

iPhone: Navigate to another view with transition style and Back button set

I have following code which add BackButton on my view's navigation item's tabbar. It works fine.
// Add back button
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
[view.navigationController setNavigationBarHidden:NO animated:YES];
view.navigationItem.backBarButtonItem = backButton;
view.navigationController.navigationBar.barStyle = UIBarStyleBlack;
[backButton release];
I use following line to navigate to my new view controller but it gets presented with default animation.
[view.navigationController pushViewController:viewController2 animated:YES];
I want to change the way it gets presented so I tried to do it following way.
[viewController2 setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[view.navigationController presentModalViewController:viewController2 animated:YES];
This works fine but I lost my BackButton..!! Is there anyway to present my new view controller with specific transition style and also keep my back button as is?
Thanks.
I found the answer to your question. Put a navigation bar on your viewController2 and add a bar button to it using either interface builder or using code. Then in the action of button press
In your viewController2.m write this function and link it up with the button press if you have added the bar button through interface builder.
-(void) backButtonPressed : (id) sender
{
[self dismissModalViewControllerAnimated:YES];
}
This should solve your problem.
Doing a pushViewController will carry forward the navigationBar and all for you but in your case presenting a viewController as modalViewController will not give you the navigationBar by default so you have to add it manually in your modalViewController which is viewController2 in your case.
Please let me know if you are still facing problems. We can fix it soon and save you some time and frustration.
Cheers!!!

toggle view with UINavigationController

I have a navigation controller and a button located on the right of the navigation bar that is called toggle. When ever I press the button I basically want to toggle between a table view and a map view. How can I do this?
Can this be done by pushing and popping from the navigation stack back and forth?
Ok... what you want can be done using navigationControllers and such.
You just need to make a method in both viewControllers, and in the viewDidLoad of each put this:
[self.navigationItem setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithTitle:#"Toggle" style:UIBarButtonItemStylePlain target:self action:#selector(toggleView:)] autorelease]];
then you want this method in the first view you get to (lets say its the list view):
-(void)toggleView:(id)selector {
MapViewController *mapViewController = [[MapViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:mapViewController animated:NO]; // this pushes a view onto the stack
/* or you could use this:
[self presentModalViewController:mapViewController animated:YES];
// which slides the view up over the current view */
[mapViewController release];
}
then in the mapview:
- (void)toggleView:(id)selector {
[self.navigationController popViewControllerAnimated:YES]; // this pops back a view
/* or you went for the second option above:
[self dismissModalViewControllerAnimated:YES];
// which slides the view back down. */
}
I am doing this same thing in one of my apps, except with a segmented control. In my case, the map and the table were logically on the same hierarchical level, so using the navigation controller didn't make sense.
Basically, I instantiate both the table view and the map view when the user is at that point in the app. When I receive a button press event, I just move one view in front of the other (bringSubviewToFront). The events from both of these views (map and table) push the next view onto the controller. To make sure that the back button on the navigation controller makes sense, I just toggle the navigationItem title in the RootViewController. So, if they want to toggle the map:
[self.view bringSubviewToFront:self.map_view.view];
UIBarButtonItem *backButton =
[[UIBarButtonItem alloc] initWithTitle:#"Map" style:
UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
etc...
Since I ran into some memory problems, I also have some code that will trash the map and reset the back button title if I get a memory warning, and the toggle button delegate method will check to see if the map needs to be re-instantiated before shuffling the views. I like this better than instantiating and releasing the map every time it's toggled. Generally retaining the map has much more fluid performance, and it allows the user's state for the map to persist (as long as we don't hit the memory limit).
Hope this helps.

Back button on UINavigationController

I know that it could seem strange but i need to add a back button on the navigation Bar of the first navigationController's view. I tried like this:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Foo" style:UIBarButtonItemStyleBordered target:self action:#selector(foo:)];
self.navigationItem.backBarButtonItem=backButton;
if instead of backBarButtonItem i write leftBarButtonItem the button is showed. My problem is that i need an arrow button as the normal back button. Is this possible?
Usually this works out of the box, but sometimes with modal views / action sheets you may need this. Just before you instantiate your viewcontroller and push it onto navigationcontroller stack, try
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"Back" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
[newBackButton release];
DetailViewController *detailVC = [[DetailViewController alloc]init];
[self.navigationController pushViewController:detailVC animated:YES];
[detailVC release];
I don't think you can do that on the first NavigationController view, because you need to set the backBarButtonItem property in the parent controller, before the child controller is pushed. Also, according the to the Apple docs, the target & action of the backBarButtonItem must be nil.
This question about creating a left-arrow button on a UIToolbar may give you some ideas of how you could work around this using a custom image (for the leftBarButtonItem).
or you could also do the following - I prefer this method. I got this from a different post.
Use following psd that I derived from http://www.teehanlax.com/blog/?p=447
http://www.chrisandtennille.com/pictures/backbutton.psd
Then I just create a custom UIView that I use in the customView property of the toolbar item.
Works well for me.
Hope that helps a little
Of course you can do this. You just need to change the leftBarButtonItem's title to back
then you will get a nice left arrow button with the title back. Then you just change the selector to actually perform a method when the button is clicked. So #selector(foo:)
Here some code on how to achieve the above:
self.navigationItem.leftBarButtonItem.style = UIBarButtonItemStyleDone;
self.navigationItem.leftBarButtonItem.title = #"Back";
self.navigationItem.leftBarButtonItem.target = self;
self.navigationItem.leftBarButtonItem.action = #selector(endTextEnteringButtonAction:);
Let me know if that helps.
Apple Document says:
When this navigation item is immediately below the top item in the stack, the navigation controller derives the back button for the navigation bar from this navigation item.
So If your navigation item is the top of the Stack (as we are talking here) you can't add the back button to the navigation controller, simply because no place he can navigate back to it because it's the top item in the stack.
Updated Answer :
After I searched I found work a round to make a back button in your root view controller in Navigation controller in these link
It's very simple :)
[self.navigationItem setHidesBackButton:YES animated:YES];
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithTitle:#"Start" style:UIBarButtonItemStyleBordered target:self action:#selector(initializeStuff)];
self.navigationItem.leftBarButtonItem = backButton;

Back button of Navigation Controller does not work!

For some reason, if I try to go back to the main menu using the back button on the upper left corner, only the title returns to the previous menu, but not the view controller. View controller would return to the previous menu only if I explicitly call popViewControllerAnimated using some other button.
Is there anyway to solve this? I think I've coded something wrong. Tried googling but couldn't find any cases like mine.
I'm getting the exact same problem. Here is my code:
- (IBAction) showGameView:(id) sender {
gameView = [[TCGameViewController alloc] initWithNibName:#"TCGameViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:gameView animated:YES];
[gameView release];
}
And when I am done with gameView, I do this:
[self.navigationController setNavigationBarHidden:NO animated:YES];
But all it does when I push the 'back' button is cycle through the navigation bar, but never pops the view. I don't even know how to debug it.
In my other view, "infoView" I call the same code as before except the NavBar is never hidden, but it works just fine.
helps!
This problem can occur when you override the following method in your custom view controller:
- (UINavigationItem*)navigationItem
But you don't specify a UIBarButtonItem for the leftBarButtonItem property of the returned UINavigationItem.
If you use a custom navigationItem, and want the standard back button functionality, you could add a method as follows (remember that every UIViewController has a reference to the navigationController that containts it):
- (void)backButtonTapped
{
[self.navigationController popViewControllerAnimated:YES];
}
And then setup part of the custom navigationItem as follows:
- (UINavigationItem*)navigationItem
{
UIBarButtonItem* newLeftBarButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(backButtonTapped)];
UINavigationItem* navigationItem = [[[UINavigationItem alloc] init] autorelease];
Hope this helps.

Is there a better way to hide the backBarButtonItem than this?

I have a way of hiding the back button used by the navigation controller. It's set by the previous controller, not the one managing the current view, and that makes it tricky to get to. I needed to do this in editing mode so that I could prevent the user from navigating away from the screen.
if(self.editing) {
// Get rid of the back button
UIView *emptyView = [[UIView alloc] init];;
UIBarButtonItem *emptyButton = [[[UIBarButtonItem alloc] initWithCustomView:emptyView] autorelease];
[self.navigationItem setLeftBarButtonItem:emptyButton animated:YES];
} else {
// Restore the back button
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
}
Is there a better way to do this?
use this to hide back button
[self.navigationItem setHidesBackButton:YES]
use this to show back button
[self.navigationItem setHidesBackButton:NO]
Here's the method I use in my view controller to show and hide the back button when editing is enabled and disabled:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
if (editing) {
// Disable the back button
[self.navigationItem setHidesBackButton:YES animated:YES];
}
else {
// Enable the back button
[self.navigationItem setHidesBackButton:NO animated:YES];
}
[super setEditing:editing animated:animated];
}
Make an outlet with strong (not weak as default) of the bar button from the storyboard to your view controller.
The purpose is not to loose the reference when you set the left/right bar button to nil.
Swift5:
self.navigationItem.setHidesBackButton(true, animated: false)