6

I want to programmatically set button for navigationItem.titleView.

I tried with following code but with no success;

UIBarButtonItem *navigationTitleButton = [[UIBarButtonItem alloc] initWithTitle:@"Custom" style:UIBarButtonItemStyleBordered target:self action:@selector(backToHOmePage)];

navigationTitleButton.image = [UIImage imageNamed:@"title.png"];

self.navigationItem.titleView = navigationTitleButton;

Warnng says: Incompatible pointer types assigning to 'UIView *' from 'UIBarButtonItem *__strong'

iWizard
  • 6,816
  • 19
  • 67
  • 103

10 Answers10

14

Try to use this code see if it works for you

UIView * container = [[UIView alloc]initWithFrame:CGRectZero];
UIButton * button = [[UIButton alloc]initWithFrame:CGRectZero];
[button addTarget:self action:@selector(backToHOmePage) forControlEvents:UIControlEventTouchUpInside];
[button setImage:[UIImage imageNamed:@"clanak_default.png"] forState:UIControlStateNormal];
[button sizeToFit];
[container addSubview:button];
[button release];
[container sizeToFit];
self.navigationItem.titleView = container;
[container release];
Janub
  • 1,594
  • 14
  • 26
  • 7
    Your solution works, thanks! Why is it that if UIButton is a subclass of UIView, that a UIButton can't be used directly as titleView? – cph2117 Jul 14 '15 at 14:58
  • It will work with a UIButton, UILabel, etc. You just need to initWithFrame a visible size UIView. See below the or in Evgenjy S's answer. – Chucky Aug 29 '17 at 17:15
10

You dont have to create BarItem, you need to create UIView class object;

ARC

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
view.backgroundColor = [UIColor clearColor];

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = view.frame;

[view addSubview:button];

self.navigationItem.titleView = view;

or

   UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
   button.frame = CGRectMake(0, 0, 40, 40);
   self.navigationItem.titleView = button;
Evgeniy S
  • 1,464
  • 12
  • 32
2

Swift version:

var button =  UIButton.buttonWithType(UIButtonType.Custom) as UIButton
button.frame = CGRectMake(0, 0, 100, 40) as CGRect
button.backgroundColor = UIColor.redColor()
button.setTitle("Button", forState: UIControlState.Normal)
button.addTarget(self, action: Selector("clickOnButton:"), forControlEvents: UIControlEvents.TouchUpInside)
self.navigationItem.titleView = button

Here you can see in last line button is directly set to the titleView of navigationItem which will add button at the center of navigation bar.

Action method for button is below:

func clickOnButton(button: UIButton) {

}
Esqarrouth
  • 38,543
  • 21
  • 161
  • 168
2

You can add a UIImageView as the navigationItem's titleView directly, however it will not be visible if you do not make sure it is sized. The easiest way to size it is to use sizeToFit().

In this example I also round the corners and add the ability to know if it is tapped.

override func viewDidLoad() {
    super.viewDidLoad()

    let titleIconButton = UIButton(type: .Custom)
    titleIconButton.setImage(UIImage(named: "login-icon"), forState: .Normal)
    titleIconButton.addTarget(self, action: #selector(titleIconTap), forControlEvents: .TouchUpInside)
    titleIconButton.clipsToBounds = true
    titleIconButton.layer.cornerRadius = 4
    titleIconButton.sizeToFit()
    navigationItem.titleView = titleIconButton
}

enter image description here

Michael Peterson
  • 10,383
  • 3
  • 54
  • 51
2

Here is a Swift 4 ported version of the answer from @Esqarrouth.

let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
button.backgroundColor = .red
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(clickedButton(_:)), for: .touchUpInside)
self.navigationItem.titleView = button
EmpathicSage
  • 1,265
  • 8
  • 11
1

Swift 3 Version:

    let logoButton = UIButton(type: .custom)
    logoButton.setImage(#imageLiteral(resourceName: "Logo"), for: .normal)
    logoButton.sizeToFit()
    logoButton.addTarget(self, action: #selector(tapLogo), for: .touchUpInside)

    self.navigationItem.title = ""
    self.navigationItem.titleView = logoButton
Sébastien REMY
  • 2,399
  • 21
  • 39
1

If you plan on changing the button.title at runtime, and you change the title to longer text, it will not be centered. And if you do button.sizeToFit(), it will be centered, but show the new title as "T..e".

The solution is to put the UIButton in a UIView. And constrain the button to all sides of UIView. Then just set the navigationItem.titleView to that UIView. And it will handle programmatic title changes perfectly.

Elijah
  • 8,381
  • 2
  • 55
  • 49
0

Try creating a UIButton object for your button instead of a UIBarButtonItem one. UIButton is a subclass of UIView so you should be able to set the titleView property to the UIButton you've created.

NikosM
  • 1,131
  • 7
  • 9
0

You can add your button on a view then make that view as the title view of navigation bar then you can change the title of the button at run time easily.

spider1983
  • 1,098
  • 1
  • 7
  • 14
0

This UISegmentedControl-based approach might help you: https://stackoverflow.com/a/16792575/171933 Enjoy!

Community
  • 1
  • 1
Johannes Fahrenkrug
  • 42,912
  • 19
  • 126
  • 165