How to change uinavigationbar back button text - iphone

I am currently trying to change the back button text of a subview that is loaded of a tablecell touch. However even with the way I am trying to implement it it still shows the parents title in the back button.
I am trying to load a new value into the back button inside viewdidload method like so
UIBarButtonItem *myBarButtonItem = [[UIBarButtonItem alloc] init];
myBarButtonItem.title = #"Back";
self.navigationItem.backBarButtonItem = myBarButtonItem;
[myBarButtonItem release];
however its not working.

You need to change self.navigationItem.backBarButtonItem from previous view, not current view (I know, it seems to be a little bit illogical). For example, in your table view you can do the following:
- (void)viewDidLoad
{
[super viewDidLoad];
[self setTitle:#"My title"];
UIBarButtonItem *boton = [[UIBarButtonItem alloc] initWithTitle:#"Custom back button text" style:UIBarButtonItemStyleBordered target:self action:#selector(mySelector:)];
self.navigationItem.backBarButtonItem = boton;
[boton release];
}

This is where the documentation is not so clear until you have read and re-read and play around with each settings.
To change the title of the default back button add this line in viewDidLoad()
self.navigationController.navigationBar.topItem.title = #"Your Label";
If you want the button to be invisible - then set the value to #"" empty string.

Okay figured it out, I posted this code in the parent views tableView:didSelectRowAtIndexPath: method. this is how my one looks with multiple tablecells the user can select. Hope this helps.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
if (indexPath.section == 0) { //--- picks (first) section
ChildViewController *childViewController = [[ChildViewController alloc] initWithNibName:#"ChildViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:childViewController animated:YES];
//--- this sets the back button to "Back" every time you load the child view.
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style: UIBarButtonItemStyleBordered target:nil action:nil] autorelease];
if(indexPath.row == 0) { //--- picks row
childViewController.title = #"Bike";
}
if(indexPath.row == 1) {
childViewController.title = #"Model";
}
[vehicleSearchResponseTableViewController release];
}
}

The best way with Xcode 5 to change the back button name is to edit the Back Button field in IB of the Navigation Item on the View Controller to which the back button will return. For example, if you have a list TableViewController that goes to a detail screen, change the Back Button on the list TableViewController's Navigation item (in IB) to change the back button name that the detail screen displays.

It's not gonna work the way you're trying to do. Navigation button will always have title of previous view. What you can do though - change title of first view before pushing the new one. This is the only was I could find to solve same problem.

Your code looks fine so far.
Is this code executed before the
[super viewDidLoad];
statement (wrong) or after it (good)?

After viewDidLoad
self.navigationController!.navigationBar.backItem?.title = "Back"

My suggestion was to add a separate Label to parents Page title Bar.
Worked fine for me.
let titleLabel = UILabel(frame: CGRect(x: (view.frame.width * (3/8)), y: 0, width: (view.frame.width * 0.25 ), height:30))
titleLabel.text = "Title"
titleLabel.textAlignment = .center
titleLabel.textColor = UIColor.white
titleLabel.font = UIFont.systemFont(ofSize: 20)
navigationItem.titleView = titleLabel

This article should do what you want.
From the author:
As you can see above, all you need to do is set the leftBarButtonItem of the controller and it will hide the back button. The selector handleBack now handles the back event and you need to then manually pop the view controller off the UINavigationController’s stack. You can implement any of your own code in there, even blocking leaving the page.

A good way to do this is to set the title of the back button in the parent view controller before calling the child like this:
[self.navigationItem.backBarButtonItem setTitle:#"Your Custom Title"];
This title will be placed in the back button on the child view. The important point to get here is this title is used in the child view as the back button to the parent view.

Related

how to change uinavigation controller back button action

I have a UINavigationController and I have to keep the the default back button "the back arrow style" I just want to ask if I can change the back button action without build new one and change its style
AFAIK you cannot change the action of the default back button itself but you can place a UIBarButtonItem as leftBarButtonItem there and assign your own action.
If there is a leftBarButtonItem defined then this is shown and not the default back button.
However, keep the GUI guidelines in mind when doing tricks like this.
No. If you want a custom back button, you have to create a custom UIBarButtonItem, then assign it to the appropriate property:
self.navigationItem.backBarButtonItem = myCustomBackItem;
The back button in UINavigationBar is generated automatically as soon as u Push a new UIView. In order for you to customize the Back button is to Create a new UIToolBar + a UIBarButtonItem with custom view.
Code below is the sample to use a custom UIBarButtonItem in UIToolBar.
// create button
UIButton* backButton = [UIButton buttonWithType:101]; // left-pointing shape!
[backButton addTarget:self action:#selector(backAction) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:#"Back" forState:UIControlStateNormal];
// create button item -- possible because UIButton subclasses UIView!
UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
// add to toolbar, or to a navbar (you should only have one of these!)
[toolbar setItems:[NSArray arrayWithObject:backItem]];
navItem.leftBarButtonItem = backItem;
Link below is the design of iOS buttons in PSD format for further modifications.
http://www.chrisandtennille.com/pictures/backbutton.psd
You can make custom button and can make action on it but you can not change default backButton action.....
self.navigationItem.leftBarButtonItem = getBackBtn;
The UINavigationController sends a message to it's delegate when it pushes and pops a ViewController.
You can find out when the back button gets pressed by implementing the following and adding <UINavigationControllerDelegate> in your .h file
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.delegate = self;
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
self.navigationController.delegate = nil;
}
-(void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated{
//Test here if the View Controller being shown next is right below the current
// ViewController in the navigation stack
//
//Test by:
// 1. comparing classes, or
// 2. checking for a unique tag that you previously assigned, or
// 3. comparing against the [navigationController viewControllers][n-2]
// where n is the number of items in the array
if ([viewController isKindOfClass:NSClassFromString(#"ViewControllerClassThatGetsPushedOnBACK")){
//back button has been pressed
}
if (viewController.tag == myUniqueTagIdentifier){
//back button has been pressed
}
if ([navigationController.viewControllers[navigationController.viewControllers.count-2]==viewController]){
//back button has been pressed
}
}
Apple Docs UINavigationController Class Reference:
The root view controller is at index 0 in the array, the back view
controller is at index n-2, and the top controller is at index n-1,
where n is the number of items in the array.

UINavigationItem BackBarButtonItem not replaced

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.

Why would a UINavigationController's toolbarItems refresh 4-5 seconds after the rest of the view?

I do have the code for this, but since it's in so many files, I'll only narrow it down and post it if necessary. I believe I might just be missing some method call or thread thing... I have a navigation controller with a table view as its view and a toolbar with three buttons.
Touching one of the three buttons causes a method to be called that changes the table view's dataSource, reloads the table, and also changes the titles (and possibly number) of buttons on the toolbar (# of buttons can be 0~3).
There is also a rightBarButtonItem that pushes on a modal vc which, upon dismissal, changes the dataSource and reloads the table and buttons as well.
The problem: touching a button (#1) causes immediate effects: the buttons are redrawn with new titles and the tableView's data reloaded. But when the modal vc is dismissed (table's setter properties should cause data to be reloaded before viewWillAppear of the table vc), everything is fine except for the buttons! The correct number of UIBarButtonItems appear on the toolbar, but their titles are blank. I NSLog'd inside the method that sets the toolbarItems property, and after the log says "UIBBI array set", the buttons appear, with [blank] titles, then 4-5 seconds later, the titles appear (long after the method to set them has returned).
Do I need to be doing something in a different thread? Pushing this tvc on has no problems, and the method described in #1 also does not produce the same blank-then-titled effects... So, I'm stumped. Sorry for the LENGTHY explanation...trying to be complete. But any help would be very appreciated!
Code which is called when the self.resultsArray is updated (from this view, the previous one which pushes it on, or the modal:
- (void)updateBestGuessesButtons
{
if (self.resultsArray.count == 0 || self.resultsArray.count == 1 || !self.bestGuesses) {
[self.navigationController setToolbarHidden:YES animated:YES];
return;
}
[self.navigationController setToolbarHidden:NO animated:YES];
NSMutableArray *toolbarItems = [[NSMutableArray alloc] initWithObjects:[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil], nil];
for (NSString *guess in self.bestGuesses) {
UIBarButtonItem *button = [[UIBarButtonItem alloc]
initWithTitle:guess
style:UIBarButtonItemStyleBordered
target:self
action:#selector(removeWordsWithLetter:)];
[toolbarItems addObject:button];
}
[toolbarItems addObject:[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil]];
[self setToolbarItems:toolbarItems animated:YES];
}
It looks like you have to set the title of the UIButton for all states,
[myButton setTitle:#"Foo" forState:UIControlStateNormal];
[myButton setTitle:#"Foo" forState:UIControlStateHighlighted];
[myButton setTitle:#"Foo" forState:UIControlStateSelected];
// .. and so on
OK -- my resolution to this issue was to move the button creation to the viewDidLoad event.

My navigationbar doesn't show a back button if the previous view controller has no title

How do i make it show the back button, with the title "Back"? It shows perfectly well if the previous view controller has a title.
Simplest solution is in viewDidLoad of the view that is about to push a new one, do the following:
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationItem.backBarButtonItem = backBarButton;
[backBarButton release]
Works perfectly, no questions asked.
You can set the backBarButtonItem property of the previous viewController. So if you are have one viewcontroller "A" and you push a viewController "B". The back button will be the button backBarButtonItem on the "A" view controller.
You can also try to set the title before pushing the new view controller. For example:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self setTitle:#"back"];
// Push new view controller...
}
and then set it back to #"" in your -viewWillAppear.

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;