leftbarbuttonitem does not show up in the navigation bar - ios

I've been developing an iOS app and have been having issues with using an image as the left bar button item in the navigation bar. I have attempted this in the following ways:
UIImage *backButtonImage = [UIImage imageNamed:#"backbuttonCB"];
CGRect buttonFrame = CGRectMake(0, 0, backButtonImage.size.width, backButtonImage.size.height);
UIButton *backButton = [[UIButton alloc] initWithFrame:buttonFrame];
[backButton setImage:backButtonImage forState:UIControlStateNormal];
UIBarButtonItem *backBarButtonItem= [[UIBarButtonItem alloc] initWithCustomView: backButton];
self.navigationItem.leftBarButtonItem = backBarButtonItem;
The bar button never seems to display while running the app.
I then proceeded to try this other method as follows.
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"backbuttonCB"] style:UIBarButtonItemStylePlain target:nil action:#selector(methodname)];
This method actually worked. However, the image displayed was tinted blue and did not look like it was meant to. Changing the tint colour of this image did not help.
Any idea how I can solve this problem?
EDIT: More information, if it helps.
This is the first view in the navigation stack. The navigation stack is displayed modally i.e. there is a previous view controller and there is a modal segue between the previous view controller and the navigation controller. This is the first view in the navigation stack.
EDIT: THE PROBLEM IS FIXED.
I think it was a bug in xcode because when I restarted xcode and tested it with an actual device instead of the emulator, it worked fine. However, still doesn't seem to work on an emulator.

Try setting your leftBarButtonItem this way. While presenting modally it doesn't shows up.
self.navigationController?.navigationBar.topItem.leftBarButtonItem =

Calling myButton.sizeToFit() before assigning to leftBarButtonItem helped me.
let cancelButton = UIButton()
cancelButton.backgroundColor = .red
cancelButton.setTitle("Common/Cancel".localized, for: .normal)
cancelButton.sizeToFit() //!!!
let cancelBarButton = UIBarButtonItem(customView: cancelButton)
navigationItem.leftBarButtonItem = cancelBarButton

Try to use this code,
self.navigationItem.hidesBackButton=YES;
UIImage *buttonImage = [UIImage imageNamed:#"Back"];
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame = CGRectMake(0.0,0.0,buttonImage.size.width,buttonImage.size.height);
[aButton addTarget:self action:#selector(backBtnTapped) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:aButton];
self.navigationItem.leftBarButtonItem = backButton;

I had the same problem. To see the button, I had to change the tint color, here's the code in Swift:
self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(image:UIImage.init(named: "btn_back_default")!, style:UIBarButtonItemStyle.Plain, target: self, action: Selector("back"))
self.navigationItem.leftBarButtonItem?.tintColor = UIColor.whiteColor()

Updated for Swift 5:
let image = UIImage(named: "iconClose")
let button = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self.cancel))
navigationItem.leftBarButtonItem = button

For me the problem on iOS 13 was due to the use of the native Apple SF Symbols as the image of the UIBarButtonItem.
My advice would be to use add your image to the assets or if you prefer using SF Symbols use the "#available" selector to used them in versions > iOS 14.0, see:
var img: UIImage
var backButton: UIBarButtonItem
if #available(iOS 14.0, *) {
img = UIImage(systemName: "chevron.backward")!
backButton = UIBarButtonItem(image: img, style: .plain, target: self, action: #selector(foo))
} else {
// add your image to the project's assets first and make sure that the name is the same
img = UIImage(named: "my-custom-image")!
backButton = UIBarButtonItem(image: img, style: .plain, target: self, action: #selector(foo))
}
self.navigationItem.leftBarButtonItem = backButton

Replace your code to initialize the button as a customType like this:
UIImage *backButtonImage = [UIImage imageNamed:#"backButtonCB"];
CGRect buttonFrame = CGRectMake(0, 0, backButtonImage.size.width, backButtonImage.size.height);
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setFrame:buttonFrame];
[backButton setImage:backButtonImage forState:UIControlStateNormal];
UIBarButtonItem *backBarButtonItem= [[UIBarButtonItem alloc] initWithCustomView: backButton];
self.navigationItem.leftBarButtonItem = backBarButtonItem;
Hope it helps....:)

Add a Navigation Item to the Views storyboard and create an outlet for it in the ViewController. Then, use your outlet instead of self.navigationController?.navigationItem to reference leftBarButtonItem.

Related

Navigation bar item not showing complete

I can see just this (text should be "item" and it is showing "I...m")
When I try to add a navigation bar item using the storyboard. Anybody know why?
This is how I'm adding that button:
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Item", style: .Plain, target: self, action: nil)
Put a UIButton as the customView of the UIBarButton to set a custom width of the UIBarButton.
// create the nav bar back button
UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 24)];
[backButton setTitle:#"Item" forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = buttonItem;

Create a custom left back button on UINavigationBar WITH the standard arrow on the left

When I create a custom back button, I use the following code:
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc]initWithTitle:#"Yeah" style:UIBarButtonItemStyleBordered target:self action:#selector(backButtonPressed:)];
self.navigationItem.leftBarButtonItem = leftButton;
This works fine, and I obtain this result:
I would have the same result, but with an arrow on the left, like this (when it's a standard back button, not a custom one):
How can I simply add this arrow ?
Finally, here's the snippet I use to define the back button's title with the standard left arrow in the current view, not in the parent view :
- (void)viewDidLoad {
[super viewDidLoad];
[self setTitle:#"Current View"];
// Get the previous view controller
UIViewController *previousVC = [self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count - 2];
// Create a UIBarButtonItem
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"FooBar" style:UIBarButtonItemStyleBordered target:self action:#selector(yourSelector)];
// Associate the barButtonItem to the previous view
[previousVC.navigationItem setBackBarButtonItem:barButtonItem];
}
Here's the result :
Note : However, since it's not possible to add an action on a backBarButtonItem, you can refer to this great post if you want it to.
Updated for Swift
// Prev - no chevron...
//navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back !", style: .plain, target: self, action: #selector(backPressed))
// adds the chevron
let vc = navigationController?.viewControllers.first
let button = UIBarButtonItem(title: "Go Back", style: .plain, target: self, action: #selector(backPressed))
vc?.navigationItem.backBarButtonItem = button
The easiest thing to do would be to set the title, in the parent controller (i.e. the one you want to nav back to). If you don't want this to be the same as the actual title displayed in that VC's view, you can change the title in viewWillDisappear to what you want on the next VC's back button, and then change it back to what you want in the parent in viewWillAppear.
If you are using storyboards, you can also set the back title directly in IB.
Finally, in order to create a custom back button, you can do something like:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:#"Details" style:UIBarButtonItemStyleBordered target:nil action:nil];
...just be sure to do this in the presenting (or parent) view controller, not the view controller being loaded (the presented controller).
UIButton * backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton addTarget:self action:#selector(popViewController) forControlEvents:UIControlEventTouchUpInside];
[backButton setFrame:FRAME_DEFINE
[backButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[backButton setExclusiveTouch:YES];
[backButton setImage:[UIImage imageNamed:BACK_BUTTON_DEFAULT_ICON] forState:UIControlStateNormal];
[backButton setTitle:#"BACK" forState:UIControlStateNormal];
[backButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
UIBarButtonItem *backMenuBarButton = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = backMenuBarButton;
well you need to go with a background image and with title and
// Creates a back button instead of default behaviour (displaying title of previous screen)
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"back_arrow.png"]
style:UIBarButtonItemStyleBordered
target:self
action:#selector(backAction)];
tipsDetailViewController.navigationItem.leftBarButtonItem = backButton;
[backButton release];
I use code like:
UIBarButtonItem *leftBar = [[UIBarButtonItem alloc] init];
leftBar.title = #"Back";//Details
self.navigationController.navigationBar.topItem.backBarButtonItem = leftBar;
For Swift, using Erzekiel's answer as the basis for this, you can simplify it to -
extension UIViewController {
func setBackButtonTitle(to title: String) {
let barButtonItem = UIBarButtonItem(title: title, style: .plain, target: self, action: nil)
self.navigationItem.backBarButtonItem = barButtonItem
}
}
This should be called from the parent viewController, eg in viewWillDisappear -
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.setBackButtonTitle(to: "Back"))
}

Cant set image for UIBarButtonItem

I'm trying to set image for my UIBarButtonItem and I can't manage to do that. I tried two times, and in first case I get my image in right place, but when I click on button nothing happens (it should pop out a new window, but nothing works). There is the piece of code I have used:
UIImage *faceImage = [UIImage imageNamed:#"plus_button.png"];
UIButton *face = [UIButton buttonWithType:UIButtonTypeCustom];
face.bounds = CGRectMake( 0, 0, faceImage.size.width, faceImage.size.height );
[face setImage:faceImage forState:UIControlStateNormal];
UIBarButtonItem *faceBtn = [[[UIBarButtonItem alloc] initWithCustomView:face]initWithImage:faceImage style:UIBarButtonItemStylePlain target:self action:#selector(addProduct:)];
self.navigationItem.leftBarButtonItem = faceBtn;
In second case, I set image on button and new window appears as it should be, but there is not only my custom image I want, but also it show "borders", it looks like image was put in center on default button. Obviously I want only my image, not borders, only my image. There is piece of code I have used in second case:
UIBarButtonItem *addButton = [[UIBarButtonItem alloc]initWithImage:faceImage style:UIBarStyleDefault target:self action:#selector(addProduct:)];
self.navigationItem.leftBarButtonItem = addButton;
Please help me to solve the problem, any help would be appreciated, thank you!
try this ... change it's method, image according to you
UIButton *button1=[UIButton buttonWithType:UIButtonTypeCustom];
[button1 setFrame:CGRectMake(10.0, 2.0, 45.0, 40.0)];
[button1 addTarget:self action:#selector(showLeft:) forControlEvents:UIControlEventTouchUpInside];
[button1 setImage:[UIImage imageNamed:#"left-arrow-button.png"] forState:UIControlStateNormal];
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithCustomView:button1];
self.navigationItem.leftBarButtonItem = button;
Or... just write two lines of iOS 8 Swift code. (Might even work in iOS 7)
let doneButtonAsLeftArrow = UIBarButtonItem(image: UIImage(named: "LeftArrow24x24.png"), style: .Plain, target: self, action: "doneButtonPushed")
navigationItem.leftBarButtonItem = doneButtonAsLeftArrow
I have modified your code and tested the image showing in the barbutton. Please try this by yourself. And please let me know if you face any problem on this.
UIImage *faceImage = [UIImage imageNamed:#"Badge.png"];
UIButton *face = [UIButton buttonWithType:UIButtonTypeCustom];
face.bounds = CGRectMake( 0, 0, faceImage.size.width, faceImage.size.height );
[face addTarget:self action:#selector(showAlerts) forControlEvents:UIControlEventTouchUpInside];
[face setImage:faceImage forState:UIControlStateNormal];
UIBarButtonItem *faceBtn = [[UIBarButtonItem alloc] initWithCustomView:face];
self.navigationItem.leftBarButtonItem = faceBtn;
EDIT: I have added a line in my answer. I just printed a message "Hi" in log. it is working. Can you please try it?
Thanks.
Swift version of accepted answer for anyone
var settingsButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
settingsButton.frame = CGRect(origin: CGPointZero, size: CGSize(width: 36, height: 36))
settingsButton.setImage(image, forState: UIControlState.Normal)
settingsButton.addTarget(self, action: "buttonActionHere:", forControlEvents: UIControlEvents.TouchUpInside)
let rightBarButtonItem = UIBarButtonItem(customView: settingsButton)
navigationItem.setRightBarButtonItem(rightBarButtonItem, animated: true)
UIBarButtonItem *addButton = [[UIBarButtonItem alloc]initWithImage:faceImage style: UIButtonTypeCustom target:self action:#selector(addProduct:)];
self.navigationItem.leftBarButtonItem = addButton;
u were creating a default button, you need to create a UIButtonTypeCustom type button...

How to add multiple UIBarButtonItem on LEFT side of UINavigationBar with a BACK button

I'm able to follow http://blog.blackwhale.at/2009/06/uibuttons-in-uinavigationbar/ to add multiple buttons on the RIGHT side of the UINavigationBar. However, I cannot find any solution to add multiple buttons on the LEFT side. I want to add an "Edit" button next to the Back button in the UINavigation Bar for my iPad app. It's kinda like the "Sign Out" and "Edit" buttons in the iPad YouTube app.
Anyone has any idea on how to implement it?
Thanks
let editImage = UIImage(named: "YourImageName1")!
let searchImage = UIImage(named: "YourImageName2")!
let editButton = UIBarButtonItem(image: editImage, style:
.Plain, target: self, action: "didTapEditButton:")
let searchButton = UIBarButtonItem(image: searchImage, style:
.Plain, target: self, action: "didTapSearchButton:")
navigationItem.leftBarButtonItems = [editButton, searchButton]
And In the End Make Functions For Tapping Buttons
func didTapEditButton(sender: AnyObject)
{
...
}
func didTapSearchButton(sender: AnyObject)
{
...
}
You could try to add a UIView to the left side and add the buttons in programmatically, however there doesn't seem to be a better way. This may be how the tutorial you listed works, however I did not check. If you need a code example I can provide one.
This will solve your problem,
UIView *leftView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 30)];
UIButton *myButton2 = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton2 setImage:[UIImage imageNamed:#"Main_Menu_SearchIcon.png"] forState:UIControlStateNormal];
myButton2.frame = CGRectMake(0.0, 0.0, 70,30);
[myButton2 addTarget:self action:#selector(openSetting:) forControlEvents:UIControlEventTouchUpInside];
myButton.showsTouchWhenHighlighted = myButton2.showsTouchWhenHighlighted = YES;
UIButton *myButton3 = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton3 setImage:[UIImage imageNamed:#"Main_Menu_SearchIcon.png"] forState:UIControlStateNormal];
myButton3.frame = CGRectMake(50.0, 0.0, 70,30);
[myButton3 addTarget:self action:#selector(openSetting:) forControlEvents:UIControlEventTouchUpInside];
myButton.showsTouchWhenHighlighted = myButton3.showsTouchWhenHighlighted = YES;
[leftView addSubview:myButton2];
[leftView addSubview:myButton3];
UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:self.tabBarItem.title];
UINavigationBar *naviBarObj = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 60)];
naviBarObj.barTintColor = [UIColor lightGrayColor];
naviBarObj.items = [NSArray arrayWithObjects:item, nil];
naviBarObj.topItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftView];

How to add a button to UINavigationBar?

How to add a button to UINavigationBar programmatically?
Sample code to set the rightbutton on a NavigationBar.
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:nil action:nil];
UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:#"Title"];
item.rightBarButtonItem = rightButton;
item.hidesBackButton = YES;
[bar pushNavigationItem:item animated:NO];
But normally you would have a NavigationController, enabling you to write:
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:nil action:nil];
self.navigationItem.rightBarButtonItem = rightButton;
The answers above are good, but I'd like to flesh them out with a few more tips:
If you want to modify the title of the back button (the arrow-y looking one at the left of the navigation bar) you MUST do it in the PREVIOUS view controller, not the one for which it will display. It's like saying "hey, if you ever push another view controller on top of this one, call the back button "Back" (or whatever) instead of the default."
If you want to hide the back button during a special state, such as while a UIPickerView is displayed, use self.navigationItem.hidesBackButton = YES; and remember to set it back when you leave the special state.
If you want to display one of the special symbolic buttons, use the form initWithBarButtonSystemItem:target:action with a value like UIBarButtonSystemItemAdd
Remember, the meaning of that symbol is up to you, but be careful of the Human Interface Guidelines. Using UIBarButtonSystemItemAdd to mean deleting an item will probably get your application rejected.
Adding custom button to navigation bar ( with image for buttonItem and specifying action method (void)openView{} and).
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 32, 32);
[button setImage:[UIImage imageNamed:#"settings_b.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(openView) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButton=[[UIBarButtonItem alloc] init];
[barButton setCustomView:button];
self.navigationItem.rightBarButtonItem=barButton;
[button release];
[barButton release];
The example below will display a button with a title "Contact" on the navigation bar on the right. Its action calls a method named "contact" from the viewcontroller. Without this line the right button is not visible.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Contact"
style:UIBarButtonItemStylePlain target:self action:#selector(contact:)];;
In Swift 2, you would do:
let rightButton: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = rightButton
(Not a major change) In Swift 4/5, it will be:
let rightButton: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = rightButton
Why not use the following:
(from Draw custom Back button on iPhone Navigation Bar)
// Add left
UINavigationItem *previousItem = [[UINavigationItem alloc] initWithTitle:#"Back title"];
UINavigationItem *currentItem = [[UINavigationItem alloc] initWithTitle:#"Main Title"];
[self.navigationController.navigationBar setItems:[NSArray arrayWithObjects:previousItem, currentItem, nil] animated:YES];
// set the delegate to self
[self.navigationController.navigationBar setDelegate:self];
swift 3
let cancelBarButton = UIBarButtonItem(title: "Cancel", style: .done, target: self, action: #selector(cancelPressed(_:)))
cancelBarButton.setTitleTextAttributes( [NSFontAttributeName : UIFont.cancelBarButtonFont(),
NSForegroundColorAttributeName : UIColor.white], for: .normal)
self.navigationItem.leftBarButtonItem = cancelBarButton
func cancelPressed(_ sender: UIBarButtonItem ) {
self.dismiss(animated: true, completion: nil)
}

Resources