iOS 7 BarButtonItem with image and title - objective-c

I'm trying to figure out how can I achieve something like this:
This is a toolbar and I'd like to keep the button title text without having to create the whole image with icon AND text. How can I add the icon to the left of the UIBarButtonItem while keeping the text set with:
UIBarButtonItem *customBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Button" style:UIBarButtonItemStyleBordered target:nil action:nil];
EDIT
This is what I achieved with the following code:
UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
[customButton setImage:[UIImage imageNamed:#"Test"] forState:UIControlStateNormal];
[customButton setTitle:#"Button" forState:UIControlStateNormal];
customButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 0);
[customButton sizeToFit];
UIBarButtonItem *customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customButton];
Two issues here: the first is the size of the UIButton and the second is that, as you can see from the gif, the button doesn't animate properly when I tap inside the button and when I release the tap. Any ideas?

You can embed a UIButton as a custom view inside your UIBarButtonItem. You can create your UIButton however you want, including with an image and text, using -setImage:forState: and -setTitle:forState:.
UIButton* customButton = [UIButton buttonWithType:UIButtonTypeCustom];
[customButton setImage:[UIImage imageNamed:#"image"] forState:UIControlStateNormal];
[customButton setTitle:#"Button" forState:UIControlStateNormal];
[customButton sizeToFit];
UIBarButtonItem* customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customButton];
self.navigationItem.leftBarButtonItem = customBarButtonItem; // or self.navigationItem.rightBarButtonItem
Note that when doing this, you'll need to attach your IBAction methods to customButton, not to customBarButtonItem.
For more info, see the documentation for initWithCustomView:.
You can also do all of this in interface builder just by dragging a UIButton to the left bar button/right bar button slot on a navigation bar.

I was not satisfied with all solutions found on stack overflow becauseI like how UIBarButtonItenm convert images so they are displayed correctly and they can be changed with tint colour. So i discovered this solution that I can use nicely with not much code... End effect is similar to toolbar in facebook and other current apps...
When you change tint colour of view contained in UIBArButtonItem colours of image and title change accordingly, really cool , I do not have to create special images at all.
This code is called from each button like that Competition Button, and also Button is set as referencing outlet...
- (void)selectButton:(UIButton *)sender {
_competitionButton.superview.tintColor = [UIColor lightGrayColor];
_usersButton.superview.tintColor = [UIColor lightGrayColor];
_managementButton.superview.tintColor = [UIColor lightGrayColor];
sender.superview.tintColor = [UIColor whiteColor];
}
- (IBAction)onCompetitionButtonClick:(UIButton *)sender {
[self selectButton:sender];
[_scrollView scrollToPage:0 of:3];
}
In Button like that titled Competition there is only title and in bar button item there is image... This is how I have setup it and it works , maybe there are also other possibilities..

So I managed to do my solution programatically... Some users where complaining it does not work ... So how to create UTToolbar with image and item so that you can change color of button by tint and it magically alters image as well as title label ? My UI editor solution works for sure...
In this code can clarify things more and you can do it programatically either...
- (void)loadToolbar {
NSMutableArray *items = NSMutableArray.new;
[items add:[UIBarButtonItem createWithItem:UIBarButtonSystemItemFlexibleSpace :nil :nil]];
for (uint pageIndex = 0; pageIndex < _controllers.count; ++pageIndex) {
UIView *itemView = [UIView.alloc initWithFrame:CGRectMake(0, 0, 100, 44)];
itemView.backgroundColor = [UIColor clearColor];
itemView.tintColor = [UIColor orangeColor];
[itemView addSubview:[self createToolbarForItemView:pageIndex]];
[itemView addSubview:[self createButtonForItemView:pageIndex]];
UIBarButtonItem *item = [UIBarButtonItem.alloc initWithCustomView:itemView];
item.style = UIBarButtonItemStylePlain;
[items add:item];
[items add:[UIBarButtonItem createWithItem:UIBarButtonSystemItemFlexibleSpace :nil :nil]];
}
[_toolbar setItems:items];
}
- (UIButton *)createButtonForItemView:(uint)pageIndex {
UIButton *itemButton = [UIButton buttonWithType:UIButtonTypeSystem];
itemButton.frame = CGRectMake(0, 0, 100, 44);
itemButton.titleLabel.font = [UIFont systemFontOfSize:11];
itemButton.contentEdgeInsets = UIEdgeInsetsMake(30, 0, 0, 0);
itemButton.text = [_controllers[pageIndex] tabTitle];
itemButton.touchUp = ^(UIButton *sender) {
for (UIButton *button in _buttons) button.superview.tintColor = UI.toolBarInactiveButtonTextColor;
sender.superview.tintColor = UI.toolBarActiveButtonTextColor;
[self showPage:pageIndex];
};
[_buttons add:itemButton];
return itemButton;
}
- (UIToolbar *)createToolbarForItemView:(uint)pageIndex {
UIToolbar *itemToolbar = [UIToolbar.alloc initWithFrame:CGRectMake(0, 0, 100, 44)];
itemToolbar.tintColor = nil;
itemToolbar.barStyle = _toolbar.barStyle;
itemToolbar.translucent = _toolbar.translucent;
UIBarButtonItem *imageItem = [_controllers[pageIndex] tabImageItem];
imageItem.style = UIBarButtonItemStylePlain;
imageItem.tintColor = nil;
imageItem.imageInsets = UIEdgeInsetsMake(-10, 0, 0, 0);
itemToolbar.items = #[
[UIBarButtonItem createWithItem:UIBarButtonSystemItemFlexibleSpace :nil :nil],
imageItem,
[UIBarButtonItem createWithItem:UIBarButtonSystemItemFlexibleSpace :nil :nil]
];
return itemToolbar;
}

I solved this problem as follows:
[Button **setTitleColor**:[UIColor colorWithRed:129/255.0f green:124/255.0f blue:110/255.0f alpha:1.0f] forState:**UIControlStateHighlighted**];

Related

UINavigationBarButton not working when using customView

I would like to make a custom UIBarButtonItem that contains both image and text and also customise(reduce) the UIButton tap area. To achieve this programmatically, I am using the following code snippet. But UIButton disappears when added in UIView as subview. Could somebody guide me what is wrong ?
To reduce tap area of bar button, I am embedding custom UIButton in custom UIView.
//Set Navigation Bar
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)];
//Set title if needed
UINavigationItem * navTitle = [[UINavigationItem alloc] init];
navTitle.title = #"";
UIView *customBackView = [[UIView alloc] initWithFrame:CGRectMake(220,0,50,40)];
customBackView.backgroundColor = [UIColor clearColor];
//Here you create info button and customize it
UIButton * tempButton = [UIButton buttonWithType:UIButtonTypeSystem];
tempButton.frame=CGRectMake(240,2,40,40);
[tempButton setImage:[UIImage imageNamed:#"offline_bk.png"]
forState:UIControlStateNormal];
//Add selector to info button
[tempButton addTarget:self action:#selector(onTapDone:) forControlEvents:UIControlEventTouchUpInside];
[customBackView addSubview:tempButton];
[customBackView bringSubviewToFront:tempButton];
UIBarButtonItem * infoButton = [[UIBarButtonItem alloc] initWithCustomView:customBackView];
//In this case your button will be on the right side
navTitle.rightBarButtonItem = infoButton;
//Add NavigationBar on main view
navBar.items = #[navTitle];
[self.view addSubview:navBar];
Because your tempbutton is going out of bound of custom back view. You set the y origin value to 2 and x origin value to 240 which is causing button to go out of bound of custom back view.
Try this code:
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)];
//Set title if needed
UINavigationItem * navTitle = [[UINavigationItem alloc] init];
navTitle.title = #"";
UIView *customBackView = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,50)];
customBackView.backgroundColor = [UIColor clearColor];
//Here you create info button and customize it
UIButton * tempButton = [UIButton buttonWithType:UIButtonTypeSystem];
tempButton.frame=CGRectMake(4,2,40,40);
[tempButton setImage:[UIImage imageNamed:#"offline_bk.png"]
forState:UIControlStateNormal];
//Add selector to info button
[tempButton addTarget:self action:#selector(onTapDone:) forControlEvents:UIControlEventTouchUpInside];
[customBackView addSubview:tempButton];
[customBackView bringSubviewToFront:tempButton];
UIBarButtonItem * infoButton = [[UIBarButtonItem alloc] initWithCustomView:customBackView];
//In this case your button will be on the right side
navTitle.rightBarButtonItem = infoButton;
//Add NavigationBar on main view
navBar.items = #[navTitle];
[self.view addSubview:navBar];
[self.view bringSubviewToFront:navBar];

picture appears as white space in button

I downloaded from a free icon DB a thumb up icon, its size is too large for a button and it had white background.I decided to open it in pixelmator resized the icon and removed the background. when opening it with preview it looks great but when its set to be the button's image in xcode it appears as a white circle.
here is the icon after edit (30x30 png)
and this is how it looks on the button
what should I do to fix this?
edit/ upadte:
I tried #yunas code and it works in the navigation bar not for the toolbar (didn't even show the button).
Trying this code:
UIImage* image = [UIImage imageNamed:#"imageName"];
UIBarButtonItem *likeBtn = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:#selector(action_clicked:)];
NSArray* toolbarItems = [NSArray arrayWithObjects:likeBtn,nil];
self.toolbarItems = toolbarItems;
self.navigationController.toolbarHidden = NO;
resulted again in a button with the white drawing
So I was wondering: Is it even possible to have colored buttons in the toolbar? maybe i'm trying the imposible...
edit/ upadte II - the solution: wrapping a UIButton inside a UIBarButtonItem
#interface StatusUIBarButtonItem : UIBarButtonItem
- (id) initWithStatus: (enum StatusEnum)p_statusEnum;
#end
#implementation StatusUIBarButtonItem
- (instancetype)initWithStatus:(enum StatusEnum)p_statusEnum
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[self getStatusImage] forState:UIControlStateNormal];
[button addTarget:self action:#selector(status_Clicked:) forControlEvents:UIControlEventTouchUpInside];
[button setFrame:CGRectMake(0, 0, 20, 20)];
self = [super initWithCustomView:button];
if (self)
{
self.statusButton = button;
}
return self;
}
#end
then in the ViewController class:
-(void) viewDidLoad
{
StatusUIBarButtonItem* stausBtn = [[StatusUIBarButtonItem alloc] initWithStatus:self.status];
NSArray* toolbarItems = [NSArray arrayWithObjects: stausBtn, nil];
self.toolbarItems = toolbarItems;
self.navigationController.toolbarHidden = NO;
}
I hope this will help others that like me want colored images in the toolbar
UIImage *buttonImage = [UIImage imageNamed:#"imageName.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:buttonImage forState:UIControlStateNormal];
button.adjustsImageWhenDisabled = NO;
button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);
[button addTarget:self action:#selector(action:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.rightBarButtonItem = customBarItem;

UINavigationBar - change UIBarButtonItem positions

I am using a UINavigationController and its bar within my app.
Now I want to change the leftBarButtonItem and rightBarButtonItem positions.
I want them to be on a different x and y position having a custom witdth and height.
But the problem is, that changing the frame does not change anything with the barButtonItem. I do not now why, but the frame always gets resetted to its original coordinates.
Here is my code which I call in viewWillAppear:
UINavigationItem *navItem = [[self.navigationBar items] lastObject];
UIView *rightview = [[UIView alloc] initWithFrame:CGRectMake(0,0,66,30)];
rightview.backgroundColor = [UIColor blueColor];
//add custom view
UIBarButtonItem *search = [[UIBarButtonItem alloc] initWithCustomView:rightview];
navItem.leftBarButtonItem = search;
The view is not starting at 0/0, the x position for example is at 5px insetead of 0.
Any suggestions on how to solve this issue?
This worked for me for the leftBarButtonItem:
If you want the UIBarButtonItem to show exactly at position (0, 0), you can create a UIButton, sets its frame to (-5, 0, width, height), assuming that the offet of a left barbutton item is (5, 0), and place that in a UIView that you set as leftBarButtonItem.
#import "UINavigationItem+CSAButtons.h"
#implementation UINavigationItem (CSAButtons)
- (void) makeLeftBarButtonWithTarget:(id)target action:(SEL)action {
UIImage * imageNormal = [UIImage imageNamed:#"normal.png"];
UIImage * imageHighlighted = [UIImage imageNamed:#"highlighted.png"];
UIImage * imageDisabled = [UIImage imageNamed:#"disabled.png"];
// create your button
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.exclusiveTouch = YES;
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:imageNormal forState:UIControlStateNormal];
[button setBackgroundImage:imageHighlighted forState:UIControlStateHighlighted];
[button setBackgroundImage:imageDisabled forState:UIControlStateDisabled];
// set the frame of the button (better to grab actual offset of leftbarbuttonitem instead of magic numbers)
button.frame = CGRectMake(-5.0, 0.0, imageNormal.size.width, imageNormal.size.height);
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, imageNormal.size.width, imageNormal.size.height)];
[view addSubview:button];
// set the barbuttonitem to be the view
UIBarButtonItem * barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:view];
self.leftBarButtonItem = barButtonItem;
}
I dont think you have the ability to move a UIBarButtonItem but you might be able to achieve the same effect by adding that UIView element as a subview to the navigationBar (or navItem). You'll need to play with it a bit. It should allow for much more flexibility.
hope this helps.

How can I have a UIBarButtonItem with both image and text?

When I try to use an image for a UIBarButtonItem, the text isn't shown. Is there a way to show both the text and the image?
You can init the UIBarButtonItem with a custom view that has both image and text. Here's a sample that uses a UIButton.
UIImage *chatImage = [UIImage imageNamed:#"08-chat.png"];
UIButton *chatButton = [UIButton buttonWithType:UIButtonTypeCustom];
[chatButton setBackgroundImage:chatImage forState:UIControlStateNormal];
[chatButton setTitle:#"Chat" forState:UIControlStateNormal];
chatButton.frame = (CGRect) {
.size.width = 100,
.size.height = 30,
};
UIBarButtonItem *barButton= [[[UIBarButtonItem alloc] initWithCustomView:chatButton] autorelease];
self.toolbar.items = [NSArray arrayWithObject:barButton];
I suggest a way how to do this using Storyboard:
Drag and drop to ToolBar usual UIView. It automatically will be wrapped to Bar Button Item. Adjust View width in "Size inspector". Change background color of View to clear color.
Put UIButton and UILabel inside a View. You can use constraints to adjust their positions. Also you can put thier outside of a View, for example, little higher or less (like on my picture). Put Default and Highlighted images for UIButton.
Copy Bar Button Item and adjust another buttons. Add Flexible spaces.
Create outlets.
Done :). When you run app, you get Tool Bar like this:
P.S. Here you can read how to create UIToolbar subclass using .xib
Swift 4.2 with target
extension UIBarButtonItem {
convenience init(image :UIImage, title :String, target: Any?, action: Selector?) {
let button = UIButton(type: .custom)
button.setImage(image, for: .normal)
button.setTitle(title, for: .normal)
button.frame = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
if let target = target, let action = action {
button.addTarget(target, action: action, for: .touchUpInside)
}
self.init(customView: button)
}
}
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;
Kris Markel's answer is a good start (only < iOS7), but if you use tint color, it wount work for the image and the highlighted state of the button.
I've created a category that will create a UIBarButtonItem (leftBarButtonItem) that looks and behaves like a normal iOS7 back button. Have a look at: https://github.com/Zero3nna/UIBarButtonItem-DefaultBackButton
Swift Update for UIBarButtonItem with a custom view that has both image and text.
var chatImage: UIImage = UIImage(named: "YourImageName")
var rightButton : UIButton = UIButton(type: UIButtonType.custom)
rightButton.setBackgroundImage(rightImage, for: .normal)
rightButton.setTitle(title, for: .normal)
rightButton.frame.size = CGSize(width: 100, height: 30)
let menuUIBarButtonItem = UIBarButtonItem(customView: rightButton)

iPhone/iPad UIButton TitleLabel text not appearing

I created a grid of buttons. The following code creates the buttons and displays them, but there is no text on the button. Is there a setting I am missing? (Obj-C replies are fine, I'm bi-lingual)
RectangleF frame = new RectangleF (X + 3, Y + 3, cellWidth - 2, cellHeight - 2);
UIButton button = new UIButton (frame);
button.TitleLabel.Text = "Baha'i";
button.TitleLabel.Font = UIFont.FromName ("Helvetica-Bold", 15);
button.TitleLabel.TextColor = UIColor.Black;
button.TitleLabel.Frame = frame;
button.BackgroundColor = UIColor.FromWhiteAlpha(.5f,.5f);
this.AddSubview (button);
I think you want setTitle: forState:
[button setTitle:#"Baha'i" forState:UIControlStateNormal]
A UIButton inherits from UIView, so another way to add text and images, is to add subview. Example:
// My Image
UIImage *buttonImage = [UIImage imageNamed:#"myImage.png"];
UIImageView *buttonImageView = [[[UIImageView alloc]
initWithFrame:CGRectMake(0, 0,
buttonImage.size.width,buttonImage.size.height)] autorelease];
[buttonImageView setImage:buttonImage];
// My Label
UILabel* titleLabel = [[[UILabel alloc]
initWithFrame:CGRectMake(0, 0,
buttonImage.size.width, buttonImage.size.height)] autorelease];
titleLabel.text = #"My Text";
titleLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size: 11.0];
titleLabel.textColor = [UIColor blackColor];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.textAlignment = UITextAlignmentCenter;
// Create Button with Image and Label
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addSubview:buttonImageView];
[button addSubview:titleLabel];
UIButton * selectCountryBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
[selectCountryBtn setTitle:#"My Title" forState:UIControlStateNormal];
Here, I have create sample programmatically button, and then set the title for its Normal Control state, You can use your own button object for set the title string, additionally you can also set title text for another control states by change UIControlStateNormal to another required states.
In my case (Swift 4) it was the following:
btnLogin.setTitle("Welcome, " + var_name, for: [])
For swift Developers-
button.setTitle("Your button Name", for: .normal)
self.ButtonName.setTitle("Here Put Your variable model", for: .normal)
self.Button_name.titleLabel.text = #"Your title name";