How do the click events on UIBarButton - ios

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")
}

Related

self.navigationItem.backBarButtonItem cannot be set

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;

iPhone - Add "Add" Button when Edit button is selected in UITableView

i have a table view in my application which shows some items. when i click on one item, a new table view appears (with navigation controller: push). So at the top of the Table view there is now the navigationcontroller with the automatic "back" arrow to get back. i have the "edit" button enabled on the right side.
Now i want when i tap on the edit button, the Back button should disappear and a "+" add button should be there instead of the back button. Is this possible?
Or it is possible to get the Edit and Add button on the screen at the same time?
thanks
This is easy enough. Override the setEditing:animated: method of your view controller. This is called when the Edit/Done button is toggled (assuming you are using the standard editButtonItem from UIViewController).
In this method you create an "add" button and make it the left bar button item. This will hide the back button. Remove the "add" button and the back button will reappear.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
if (editing) {
// Add the + button
UIBarButtonItem *addBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addAction:)];
self.navigationItem.leftBarButtonItem = addBtn;
} else {
// remove the + button
self.navigationItem.leftBarButtonItem = nil;
}
}
Yep, this is the approach that I used:
Have a property for both the back button and the add button and set it in viewDidLoad:
self.backButton = self.navigationItem.leftBarButtonItem;
self.addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addPressed:)];
Now you just have to swap the buttons and update the TableView state accordingly when 'Edit' is pressed. Here i also change the 'Edit' button to 'Done':
- (IBAction)editBarButtonPressed:(UIBarButtonItem *)sender {
if (self.tableView.editing == NO) {
UIBarButtonItem *myButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(editBarButtonPressed:)];
self.navigationItem.rightBarButtonItem = myButton;
[self.tableView setEditing:YES animated:YES];
[self.navigationItem setLeftBarButtonItem:self.addButton animated:YES];
} else {
UIBarButtonItem *myButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(editBarButtonPressed:)];
self.navigationItem.rightBarButtonItem = myButton;
[self.tableView setEditing:NO animated:YES];
[self.navigationItem setLeftBarButtonItem:self.backButton animated:NO];
}
}
Hope this answers your question. :)
br denrase
The back arrow button is your navigation controller button. So if you want to disappear the same button then you have to write this code below:-
self.navigationItem.hidesBackButton=YES;
Now if you want to add your custom button on the navigation controller then use below code:-
UIBarButtonItem *customButton =
[[UIBarButtonItem alloc]
initWithTitle:#"Add"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(yourMethod:)];
self.navigationItem.rightBarButtonItem = customButton;
You can programmatically hide the back button when your table view begins editing, and then add the "Add" button to the left of your navigation bar.
[self.navigationItem setHidesBackButton:YES];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addButtonPressed)];
[self.navigationItem setLeftBarButtonItem:addButton];
Then, when the user presses Done, replace the "Add" button with the Back button:
[self.navigationItem setHidesBackButton:NO];
self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

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