How to create custom UIBarButtonItem with image and shortcut?

I would like to create a custom UIBarButtonItem that contains both an image and text, something like this:

enter image description here

I tried to subclass UIBarButtonItem and override this method:

- (UIView *)customView { if (!self.storedView) { UIView *temp = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 120, 44)]; UIImageView *tempImageView = [[UIImageView alloc] initWithImage:self.image]; tempImageView.frame = CGRectMake(0, 0, self.image.size.width, self.image.size.height); UILabel *tempLabel = [[UILabel alloc] initWithFrame:CGRectMake(44, 0, 100, 44)]; tempLabel.text = @"text"; [temp addSubview:tempImageView]; [temp addSubview:tempLabel]; self.storedView = temp; } return self.storedView; } 

And I use it as follows:

 UIBarButtonItem *left = [[LeftItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStylePlain target:self action:@selector(settingsPressed)]; left.title = @"Settings"; left.image = [UIImage imageNamed:@"settings.png"]; self.navigationItem.leftBarButtonItem = left; 

But using this, I get only the image, but not the label. What am I doing wrong?

+59
ios objective-c ios7
Sep 17 '13 at 8:16
source share
12 answers
 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setImage:[UIImage imageNamed:@"image.png"] forState:UIControlStateNormal]; [button addTarget:target action:@selector(buttonAction:)forControlEvents:UIControlEventTouchUpInside]; [button setFrame:CGRectMake(0, 0, 53, 31)]; UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(3, 5, 50, 20)]; [label setFont:[UIFont fontWithName:@"Arial-BoldMT" size:13]]; [label setText:title]; label.textAlignment = UITextAlignmentCenter; [label setTextColor:[UIColor whiteColor]]; [label setBackgroundColor:[UIColor clearColor]]; [button addSubview:label]; UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button]; self.navigationItem.leftBarButtonItem = barButton; 
+97
Sep 17 '13 at 8:21
source share
β€” -

You can add a custom view to the UIBarButtonItem .

In iOS 7, there is a new buttonType called UIButtonTypeSystem for UIButton that serves your purpose. Try it,

 UIView* leftButtonView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 110, 50)]; UIButton* leftButton = [UIButton buttonWithType:UIButtonTypeSystem]; leftButton.backgroundColor = [UIColor clearColor]; leftButton.frame = leftButtonView.frame; [leftButton setImage:[UIImage imageNamed:<YourImageName>] forState:UIControlStateNormal]; [leftButton setTitle:@"YourTitle" forState:UIControlStateNormal]; leftButton.tintColor = [UIColor redColor]; //Your desired color. leftButton.autoresizesSubviews = YES; leftButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin; [leftButton addTarget:self action:@selector(<YourTargetMethod>) forControlEvents:UIControlEventTouchUpInside]; [leftButtonView addSubview:leftButton]; UIBarButtonItem* leftBarButton = [[UIBarButtonItem alloc]initWithCustomView:leftButtonView]; self.navigationItem.leftBarButtonItem = leftBarButton; 
+18
Sep 17 '13 at 14:58
source share

If your BarButtonItem is in the storyboard, you can drag another button to BarButtonItem, so that a button appears inside BarButtonItem, you can add an image and a shortcut to the button.

+14
Oct 25 '14 at 12:30
source share

SWIFT version

  let button = UIButton(type: .Custom) button.setImage(UIImage(named: "icon_right"), forState: .Normal) button.addTarget(self, action: "buttonAction", forControlEvents: .TouchUpInside) button.frame = CGRectMake(0, 0, 53, 31) button.imageEdgeInsets = UIEdgeInsetsMake(-1, 32, 1, -32)//move image to the right let label = UILabel(frame: CGRectMake(3, 5, 50, 20)) label.font = UIFont(name: "Arial-BoldMT", size: 16) label.text = "title" label.textAlignment = .Center label.textColor = UIColor.whiteColor() label.backgroundColor = UIColor.clearColor() button.addSubview(label) let barButton = UIBarButtonItem(customView: button) self.navigationItem.rightBarButtonItem = barButton 
+12
Mar 23 '16 at 14:28
source share

The problem with the accepted answer is that the text of the UIBarButtonItem does not change when highlighted. The code below will display the text plus the image. UIEdgeInsetsMake moves the text to the left and the image to the right.

 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button addTarget:self action:@selector(myButtonEvent:) forControlEvents:UIControlEventTouchUpInside]; [button setFrame:CGRectMake(0, 0, 53, 32)]; [button setTitle:title forState:UIControlStateNormal]; [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [button setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted]; button.titleEdgeInsets = UIEdgeInsetsMake(-2, -20, 2, 20); button.titleLabel.font = font; button.titleLabel.textAlignment = NSTextAlignmentLeft; UIImage *image = [UIImage imageNamed:@"imageName"]; [button setImage:image forState:UIControlStateNormal]; button.imageEdgeInsets = UIEdgeInsetsMake(-1, 32, 1, -32); UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button]; 
+4
Mar 11 '14 at 23:46
source share

I wrote an answer that handles the color of the hue and the image, comparable to the usual uibarbuttonitem here ... https://stackoverflow.com/questions/220819/

+3
Feb 05 '15 at 16:07
source share

Another approach with NSAttributedString:

 NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"Button Text"]; NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init]; textAttachment.image = [UIImage imageNamed:@"buttonImage"]; textAttachment.bounds = CGRectMake(0, -3, textAttachment.image.size.width, textAttachment.image.size.height); //the origin y value depends on the size of the image to get a perfect fit NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment]; [attributedString replaceCharactersInRange:NSMakeRange(0, 0) withAttributedString:attrStringWithImage]; // Adding the image at the beginning [customButton setAttributedTitle:attributedString forState:UIControlStateNormal]; [customButton sizeToFit]; [customButton addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside]; UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithCustomView:customButton]; 
+3
Jul 07 '15 at 20:33
source share

Use UIButton as a custom view inside your UIBarButtonItem. You can create a UIButton as you wish, including with an image and text using -setImage:forState: and -setTitle:forState:

 UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setImage:[UIImage imageNamed:@"settings.png"] forState:UIControlStateNormal]; [button setTitle:@"Settings" forState:UIControlStateNormal]; [button addTarget:target action:@selector(buttonAction:)forControlEvents:UIControlEventTouchUpInside]; [button sizeToFit]; UIBarButtonItem* barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button]; self.navigationItem.leftBarButtonItem = barButtonItem; 

this can be done using the interface designer by simply dragging the UIButton into the slot on the left panel button in the navigation panel.

+3
Dec 10 '15 at 21:00
source share
 UIImage *image = [UIImage imageNamed:@"icon.png"]; UIImage *backgroundSelected = [UIImage imageNamed:@"icon_selected.png"]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button addTarget:self action:@selector(ButtonTapped:event:)forControlEvents:UIControlEventTouchUpInside]; //adding action [button setBackgroundImage:image forState:UIControlStateNormal]; [button setBackgroundImage:backgroundSelected forState:UIControlStateSelected]; button.frame = CGRectMake(0 ,0,35,35); 

then make this button as a custom panel

  UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView: button];
 self.navigationItem.leftBarButtonItem = barButton; 
+2
Sep 17 '13 at 8:30
source share

This is an updated version of ripegooseberry answer for Swift 3

  let button = UIButton(type: .custom) button.setImage(UIImage(named: "icon_right"), for: .normal) button.addTarget(self, action: Selector(("buttonAction")), for: .touchUpInside) button.frame = CGRect(x: 0, y: 0, width: 53, height: 31) button.imageEdgeInsets = UIEdgeInsetsMake(-1, 32, 1, -32)//move image to the right let label = UILabel(frame: CGRect(x: 3, y: 5, width: 50, height: 20)) label.font = UIFont(name: "Arial-BoldMT", size: 16) label.text = "title" label.textAlignment = .center label.textColor = UIColor.white label.backgroundColor = UIColor.clear button.addSubview(label) let barButton = UIBarButtonItem(customView: button) self.navigationItem.rightBarButtonItem = barButton 
+2
Jun 15 '17 at 16:15
source share

Amazing solution! I wanted to add UISlider to UIToolbar, and I did it that way! Remember to add a target action for your custom buttons with:

  customButton.targetForAction(#selector(addTapped), withSender: self) 

This way you can control your buttons :)

+1
Jul 27 '16 at 19:30
source share

Here my solution is based on previous answers. May be helpful.

 extension UIBarButtonItem { static func button(image: UIImage, title: String, target: Any, action: Selector) -> UIBarButtonItem { let button = UIButton() button.setImage(image, for: .normal) button.addTarget(target, action: action, for: .touchUpInside) button.setTitle(title, for: .normal) button.sizeToFit() return UIBarButtonItem(customView: button) } } 
0
Dec 14 '18 at 8:20
source share



All Articles