self.navigationItem.backBarButtonItem cannot be set - ios

I have a TableViewController named TVC and a cell in it. When I clicked on cell, TableViewController will push a new ViewController (VC) into its navigation controller. In this case, I set the [self.navigationItem.backBarButtonItem setTitle:#" "] in the viewDidLoad function of the TVC. But in the new pushed ViewController VC, the back button still has the "back" text. Can anyone explain this?
BTW, the TableViewController TVC is also pushed by another view controller VC2. I set the same function [self.navigationItem.backBarButtonItem setTitle:#" "] in the viewDidLoad function of the VC2 and the back button text displayed in the TVC is correctly hidden.

What Bimala and Ted pointed are two ways of approaching the issue. The former is to set a custom BackButtonItem and the latter is to simply use the default BackButton. But setting the title of the screen to "" may not always be acceptable. So u can choose to do the same in ViewWillDisappear method.
OBJ C:
-(void) viewWillDisappear:(BOOL)animated{
self.navigationItem.title = #"";
[super viewWillDisappear:animated];
}
SWIFT:
override func viewWillDisappear(animated: Bool) {
self.title = ""
super.viewWillDisappear(true)
}
Also you can set the title back in ViewWillappear
OBJ C:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationItem.title = #"your title";
}
SWIFT:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
self.title = "your title"
}

That's because the back button takes the title of the previous view controller. When none set it defaults to back. So set the name of the TableViewController to an empty string as follows:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = ""
}

Its my example:
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[leftView setBackgroundColor:[UIColor clearColor]];
UIButton *leftViewButton = [UIButton buttonWithType:UIButtonTypeCustom];
[leftViewButton setFrame:CGRectMake(0, 0, 30, 30)];
[leftView addSubview:leftViewButton];
[leftViewButton setImage:[UIImage imageNamed:#"NavigationBarButtonBackDefault"] forState:UIControlStateNormal];
[leftViewButton setImage:[UIImage imageNamed:#"NavigationBarButtonBackPressed"] forState:UIControlStateHighlighted];
UIBarButtonItem *barButtonItemLeft = [[UIBarButtonItem alloc] initWithCustomView:leftView];
self.navigationItem.leftBarButtonItem = barButtonItemLeft;
from documentation:
If the title of your back button is too long to fit in the available space on the navigation bar, the navigation bar may substitute the string “Back” in place of the button’s original title. The navigation bar does this only if the back button is provided by the previous view controller. If the new top-level view controller has a custom left bar button item—an object in the leftBarButtonItems or leftBarButtonItem property of its navigation item—the navigation bar does not change the button title.

If you just want to hide Back button then try:
self.navigationItem.hidesBackButton = YES;
or
self.navigationController.navigationBar.topItem.hidesBackButton = YES;
If you want to set custom Back button then use:
UIBarButtonItem *barButtonItem = [ [UIBarButtonItem alloc] initWithTitle: #"Custom"
style: UIBarButtonItemStylePlain
target: nil action: nil];
self.navigationController.navigationBar.topItem.backBarButtonItem = barButtonItem;

Related

Remove back bar button title from container view

I need empty back button title, so using category method as:
-(void)removeBackButtonTitle
{
UIBarButtonItem *newBackButton =
[[UIBarButtonItem alloc] initWithTitle:#""
style:UIBarButtonItemStylePlain
target:nil
action:nil];
[[self navigationItem] setBackBarButtonItem:newBackButton];
}
But I have a situation where I need to take Container View and some viewcontroller as child view controller and its view as a subview. Now upon navigation from this view, back button title is not setting to empty.
Simply add the following code to your viewDidLoad/viewWillAppear..
self.navigationController.navigationBar.topItem.title = #"";
This will remove Back text from that Back button. Also here you can set your own title as you desire.
#preetam .. for your case, every view controller has its lifecycle methods viewDidLoad, viewWillAppear.
Also, you are using Default navigation bar/Custom NavigationBar as you shown in screenshot.
If you're using Default, then your answer is given above. otherwise, you can remove the Back text in Storyboard itself.
Hope it helps..
Try this code and set setTitle to blank #"":
[self.navigationItem.backBarButtonItem setTitle:#""]; //make Title for backBarbutton to blank
It works for you
You need to add following lines of code in the (previous) view controllers where you don't want to display back button title.
- (void)viewWillAppear:(BOOL)animated {
self.title = #"Your Title";
}
- (void)viewWillDisappear:(BOOL)animated {
self.title = #"";
}
For Swift 3 you can use this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let backItem = UIBarButtonItem()
backItem.title = ""
navigationItem.backBarButtonItem = backItem}
Try below line of code.
UIBarButtonItem *newBackButton =
[[UIBarButtonItem alloc] initWithTitle:#""
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.leftBarButtonItems =[[NSArray alloc] initWithObjects:newBackButton, nil];
self.navigationItem.leftItemsSupplementBackButton = YES;

How do the click events on UIBarButton

As UIBarButton is not inherited from UIResponder/UIControl, how do the click events on UIBarButton work?
Just create the UIBarButtonItem's target and action properties directly.
UIBarButtonItem *barListBtn = [[UIBarButtonItem alloc] initWithTitle:#"yourTitle"
style:UIBarButtonItemStylePlain
target:self action:#selector(btnClicked:)];
self.navigationItem.rightBarButtonItem = barListBtn;
-(void)btnClicked:(UIBarButtonItem*)btn
{
NSLog(#"button tapped %#", btn.title);
}
Choice-2
- (void) viewDidLoad
{
[super viewDidLoad];
// first we create a button and set it's properties
UIBarButtonItem *myButton = [[UIBarButtonItem alloc]init];
myButton.action = #selector(doTheThing);
myButton.title = #"Hello";
myButton.target = self;
// then we add the button to the navigation bar
self.navigationItem.rightBarButtonItem = myButton;
}
// method called via selector
- (void) doTheThing {
NSLog(#"Doing the thing");
}
some additional Sample
UIBarItem is an abstract superclass for items added to a bar that appears at the bottom of the screen. Items on a bar behave in a way similar to buttons (instances of UIButton). They have a title, image, action, and target. You can also enable and disable an item on a bar.
For more details checkout the link mentioned below:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIBarItem_Class/index.html#//apple_ref/occ/cl/UIBarItem
Swift:
Add the below line in viewDidLoad
self.navigationItem.setRightBarButtonItem(UIBarButtonItem(barButtonSystemItem: .Search, target: self, action: "barButtonItemClicked:"), animated: true)
Function:
func barButtonItemClicked()
{
print("Bar button clicked")
}

Navigationbar title and back button name are same?

I created one title for navigationbar in my storyboard project ,but when I moved to next viewcontroller the back button shows the same name as my previous navigationbar(Main navigationbar) title.? Can i set separate title and back button names?
I tried following code but its not working ? why?
self.navigationItem.title=#"Recent Books";
self.navigationItem.backBarButtonItem.title=#"Back";
According to UINavigationItem Class Reference
"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. [...] If you want to specify
a custom image or title for the back button, you can assign a custom
bar button item (with your custom title or image) to this property
instead."
So try this in your first VC from where you are pushing other VC
self.navigationItem.title=#"Recent Books";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem=backButton;
Let's say you are pushing your viewcontroller A -> B
In viewcontroller A try adding this code in viewDidLoad method
UIBarButtonItem *btn_Back = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem=btn_Back;
So you will see your "Back" button in viewcontroller B
The following should solve your problem
-(void)viewDidAppear:(BOOL)animated
{
self.navigationController.navigationBar.backItem.title = #"back";
}
You can also use this Objective-C syntax
[[self.navigationController.navigationBar backItem] setTitle:#"back"];
Just do it in this way , one of the easiest way I did find till now :
Create a custom back button and add it into the Navigation Bar left button item property :
- (void)viewDidLoad
{
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backBtnImage = [UIImage imageNamed:#"Backnavigation.png"] ; // Here set the back button image
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];
[backBtn addTarget:self action:#selector(handleBack:) forControlEvents:UIControlEventTouchUpInside];
backBtn.frame = CGRectMake(0, 0, 24, 24);
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:backBtn] ;
self.navigationItem.leftBarButtonItem = backButton;
}
//Handle the Back Button Event
- (void) handleBack:(id)sender
{
// do your custom handler code here
[self.navigationController popViewControllerAnimated:YES];
}
Also, doing this way, you don't need to change the title of NavigationBar every-time.
Here is the Back Button for your reference :
You can use the below code in the viewWillAppear(animated:Bool) method of the view controller in which you want to set the backButton title of you choice :
self.navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "Back Title", style: .plain, target: nil, action: nil)

backBarButtonItem in navigation controller not showing up

I started my xcode project from a NavigationViewController template. And now, when I push a view, that view comes up with an edit button by default and no back bar button. I have commented out the editButton code and the corresponding setEditing delegate method. But I can not get the back button to show up. What am I doing wrong?
Pushing the new view:
PlaylistViewController *playlistViewController = [[PlaylistViewController alloc] init];
playlistViewController.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController:playlistViewController animated:YES];
[playlistViewController release];
in my PlaylistViewController:
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"";
// self.navigationItem.leftBarButtonItem = self.editButtonItem;
// doesn't matter if this is here or not
self.navigationItem.hidesBackButton = false;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
}
When you tell a UINavigationController to pushViewController, it automatically sets the navigationItem.leftBarButtonItem to be a button with the title of the previous UIViewController's title.
If no title is set, the default text is "Back".
If the title is set to "", no button will display at all.
self.title = #"";
Try changing this text and your back button should match the text set here.
Or you can manually override the text of the leftBarButtonItem from your new UIViewController.

Hide the rightBarButtonItem of a navigation controller

Does anyone know how to hide a rightBarButtonItem of a UINavigationController? In my application, I have an edit button as a rightBarButtonItem of a UINavigationController. I want to hide this ? UIBarButton` when some operations are done.
To Hide the right button: self.navigationItem.rightBarButtonItem = nil;
Now, to show it:
If you setup the right button in your view controller by assigning it to self.editButtonItem then simply assign it again in order to show it:
self.navigationItem.rightBarButtonItem = self.editButtonItem;
If you setup the right button in your view controller by allocating and initing a UIBarButtonItem, then simply keep a reference to the UIBarButtonItem in your view controller, and assign it again when you need to show it.
Try
self.navigationItem.rightBarButtonItem = nil;
When you want it back though you will have to instanciate a button i.e.
UIBarButtonItem *rightBarButton =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch
target:self
action:#selector(searchBar:)];
self.navigationItem.rightBarButtonItem = rightBarButton;
[rightBarButton release];
If you need to hide/show the button based on some condition, try this:
if (condition) {
self.navigationItem.rightBarButtonItem.title = #"";
self.navigationItem.rightBarButtonItem.enabled = NO;
} else {
self.navigationItem.rightBarButtonItem.title = #"my button title";
self.navigationItem.rightBarButtonItem.enabled = YES;
}
This way you don't have to save a reference to the button in a property or worry about wiring up the action on a new button.

Resources