Navigation bar item not showing complete - ios

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;

Related

leftbarbuttonitem does not show up in the navigation bar

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.

ios7 navigation bar : 3 strange dots appearing when back animation with custom button

I would like to use the back navigation animation using
[self.navigationController popViewControllerAnimated:YES]
with a custom button added to the navigation bar.
As I don't want the back button to be seen, i've hidden it with self.navigationItem.hidesBackButton = YES;
But during the back animation, on ios7 (not ios6) 3 dots can be seen sliding in the navigation bar.
They are not appearing with self.navigationItem.hidesBackButton = NO; but of course the button can be seen.
Does anyone has any idea to make them not appearing ?
If you set
self.navigationItem.hidesBackButton = YES
iOS will sometimes generate three dots inside its generic back button.
I solved the problem by setting the text on the generic back button to be empty and then I created my custom button. This is how I set the empty text:
UIBarButtonItem *backButton2 = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton2;
And then I created my custom UIButton and placed it where I wanted it like this:
UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(5, 70/2-22, 44, 44)];
[backButton setImage:[[UIImage imageNamed:#"back_button.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
backButton.tintColor = tintColor;
backButton.imageEdgeInsets = UIEdgeInsetsMake(-2, -15, 0, 0);
[backButton addTarget:self action:#selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
No need to hide the backButton, you can just add custom back button, it will hide the default button.
- (void) viewDidLoad
{
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(handleBack:)];
self.navigationItem.leftBarButtonItem = backButton;
}
- (void) handleBack:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
Just add these following lines in viewWillAppear method:
Swift:
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
Objective C:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
That's all
navigationItem.backBarButtonItem = nil
Simpler swift version :
let emptyBackButton = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
navigationItem.hidesBackButton = true
navigationItem.backBarButtonItem = emptyBackButton
You don't need to write any code just follow 4 simple step and you done it.
Select your Main.storyboard
Select Navigation Bar in Navigation Controller
Select Attributes Inspector
Clear Tint color

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

Adding both image and title to a navigation backBarButtonItem

I'm trying to add an icon (and keep the title) to the back button of my navigation controller. It seems if I set the image of the UIBarButtonItem it hides the title, so I thought I'd try a custom view. I've tried
UIButton* customButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[customButton setImage:[UIImage imageNamed:#"icon"] forState:UIControlStateNormal];
[customButton setTitle:#"Title" forState:UIControlStateNormal];
[customButton setAdjustsImageWhenHighlighted:YES];
[customButton setFrame:CGRectMake(0, 0, 125, 32)];
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithCustomView:customButton];
self.navigationItem.backBarButtonItem = backButton;
but Apple docs say that the backBarButtonItem ignores custom views, so this doesn't work.
I also tried this:
self.navigationItem.leftBarButtonItem = backButton;
self.navigationItem.hidesBackButton = YES;
but the leftBarButtonItem shows up one screen too soon and the hidesBackButton doesn't seem to hide the backBarButtonItem.
Is there another way to get both an image and title onto a navigation backBarButtonItem?
Very first hide the back button provided by UINavigationController by susing the code self.navigationItem.hidesBackButton = YES;
And set own button with image and title with the following code
UIButton* customButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[customButton setImage:[UIImage imageNamed:#"icon"] forState:UIControlStateNormal];
[customButton setTitle:#"Title" forState:UIControlStateNormal];
[customButton setAdjustsImageWhenHighlighted:YES];
[customButton setFrame:CGRectMake(0, 0, 125, 32)];
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithCustomView:customButton];
self.navigationItem.backBarButtonItem = backButton;

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