changing default icon color in iOS Toolbar - iphone

I need custom icons in toolbar (black icons on yellow toolbar background).
I tried UIBarButtonItem initWithImage constructor, but it this case
is icon displayed using alpha values, and it seems that there is no way
to change basic white icon color. I ended up using UIButton, but it will be much better,
to just change default icon color, is it possible?
UIImage *buttonImage = [UIImage imageNamed:iconName];
UIBarButtonItem *bi = [[UIBarButtonItem alloc] initWithImage:buttonImage style:UIBarButtonItemStylePlain target:nil action:nil];

You can make the toolbar yellow by setting the tint:
toolbar.tintColor = [UIColor colorWithRed:0.83 green:0.43 blue:0.57 alpha:0.5];
If you want custom UIBarButtonItem with custom image, colors etc... like you get in UIButton, one option is to create a class which encapsulates UIButton as the custom view in UIBarButtonItem. Here's my custom class - hope it helps:
#interface ENBarButtonImageItem : UIBarButtonItem
{
UIButton *_button;
}
#implementation ENBarButtonImageItem
- (id)initWithFrame:(CGRect)frame
image:(UIImage*)image
backgroundImage:(UIImage*)bgImage
{
_button = [UIButton buttonWithType:UIButtonTypeCustom];
[_button setFrame:frame];
self = [super initWithCustomView:_button];
if (self)
{
if (image)
[_button setImage:image forState:UIControlStateNormal];
if (bgImage)
[_button setBackgroundImage:bgImage forState:UIControlStateNormal];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
image:(UIImage*)image
backgroundImage:(UIImage*)bgImage
target:(id)target
action:(SEL)selector
{
self = [self initWithFrame:frame image:image backgroundImage:bgImage];
if (self)
{
[_button addTarget:target action:selector forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)dealloc
{
[super dealloc];
[_button release];
}
- (void)addTarget:(id)target action:(SEL)selector forControlEvents:(UIControlEvents)controlEvents
{
[_button addTarget:target action:selector forControlEvents:controlEvents];
}
- (void)setImage:(UIImage *)image forState:(UIControlState)state
{
[_button setImage:image forState:state];
}
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state
{
[_button setImage:image forState:state];
}

Read description of parameters of initWithImage:style:target:action:
image
The item’s image. If nil an image is not displayed.
The images displayed on the bar are derived from this image. If this image is too large to fit on the bar, it is scaled to fit. Typically, the size of a toolbar and navigation bar image is 20 x 20 points. The alpha values in the source image are used to create the images—opaque values are ignored.
Everything except alpha is ignored. Toolbar is black and white.
Subclass or use other UI frameworks, like three20 if you really need colors there.

Related

set custom back bar button universally with no title

I want to set custom back bar button for all controllers in the app. I tried using this:
[[UIBarButtonItem appearance]
setBackButtonBackgroundImage:backButtonImage
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
It sets the image. That's OK. But, what i really want to do is that, i just want a custom button for back bar button which does not contain any title etc. The code above works, but it adds automated titles and resizes the back bar button item. My need is to have a fixed frame, no-title back bar button item for all controllers in the app.
I've resolved it. Just make a category over UIViewController and import it in prefix.pch file. Then write a method: customViewWillAppear: and swizzle it with viewWillAppear method:
+(void)load{
Method viewWillAppear = class_getInstanceMethod(self, #selector(customViewWillAppear:));
Method customViewWillAppear = class_getInstanceMethod(self, #selector(viewWillAppear:));
method_exchangeImplementations(viewWillAppear, customViewWillAppear);
}
Add the above method to that category class. Then implement your customViewWillAppear method like this:
-(void)customViewWillAppear:(BOOL)animated{
[self customViewWillAppear:animated];
if([self.navigationController.viewControllers indexOfObject:self] != 0 && !self.navigationItem.hidesBackButton){
UIBarButtonItem *cancelBarButton = nil;
UIButton* cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
[cancelButton addTarget:self action:#selector(popViewControllerWithAnimation) forControlEvents:UIControlEventTouchUpInside];
[cancelButton setBackgroundImage:[UIImage imageNamed:#"yourImage.png"] forState:UIControlStateNormal];
[cancelButton sizeButtonToFit];
cancelBarButton = [[UIBarButtonItem alloc] initWithCustomView:cancelButton];
NSMutableArray * leftButtons = [NSMutableArray arrayWithObject:cancelBarButton];
[leftButtons addObjectsFromArray:self.navigationItem.leftBarButtonItems];
[self.navigationItem setLeftBarButtonItem:nil];
[self.navigationItem setLeftBarButtonItems:leftButtons];
}
[self.navigationItem setHidesBackButton:YES];
}
-(void)popViewControllerWithAnimation{
[self.navigationController popViewControllerAnimated:YES];
}
Now, for every controller in your code, you have a custom back button. This took me a lot of time to implement and figure out. Hope it'll help you guys all too.
EDIT:
Please use the following code to support iOS7> back swipe feature;
UIImage *image = [UIImage imageForName:#"some_image"];
navBar.backIndicatorImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
navBar.backIndicatorTransitionMaskImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
Create a base view controller and add the following code;
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
}
I've had a similar problem before and I've searched everywhere for a solution.
The only one I've found, which works for your problem was to implement in EVERY view controller a UILeftBarButton which does the popping.
You can change the background image the way you're doing, but if you set the text to nil or empty text (""), you're button just won't show up.
You also can't change the View of the UIBackBarButton, only it's text (so no custom button).
What i did, was set the backbutton title label alpha to zero, using appearance proxy.
My code in ViewDidLoad:
// Set back button image
if ([[self.navigationController viewControllers] objectAtIndex:0] != self) {
UIButton *btnBack = [UIButton buttonWithType:UIButtonTypeCustom];
btnBack.frame = CGRectMake(0,0,38,30);
[btnBack setBackgroundImage:[UIImage imageNamed:#"NavigationBarBackButton"] forState:UIControlStateNormal];
[btnBack addTarget:self.navigationController action:#selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *leftBtn = [[UIBarButtonItem alloc] initWithCustomView:btnBack];
[self.navigationItem setLeftBarButtonItem:leftBtn];
}
You could write a category like this,
//
// UINavigationItem+BarAditions.h
//
// Created by Satheeshwaran on on 7/5/13.
//
#import <Foundation/Foundation.h>
#interface UINavigationItem (PersonaAddition)
- (void)setCustomBackButton;
#end
//
// UINavigationItem+BarAditions.m
//
// Created by Satheeshwaran on on 7/5/13.
//
#import "UINavigationItem+PersonaAddition.h"
#implementation UINavigationItem (PersonaAddition)
- (void)setCustomBackButton
{
//customize ur back button here.
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame=CGRectMake(0, 0, 60, 30);
[backButton addTarget:target action:#selector(didPressLeftItem:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.leftBarButtonItem = barItem;
}
and import this category in all ur files and call the setCustomBackButton in all ur classes. This works fine for me, even in iOS 7.
In ViewDidLoad of all ur classes.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationItem setCustomBackButton];
}
try this code:
UIButton *tempbtn = [[UIButton alloc] init];
[tempbtn setImage:[UIImage imageNamed:#"testbtn.png"] forState:UIControlStateNormal];
UIBarButtonItem *temp = [[UIBarButtonItem alloc] initWithCustomView:tempbtn];
self.navigationItem.rightBarButtonItem = temp;

setImage method changes UIBarButtonItem width, even if image size doesn't change

I want to add a "bookmark" button to my navigation bar as a rightBarButtonItem
- (void)viewDidLoad
{
[super viewDidLoad];
// Add bookmark button
UIBarButtonItem *bookmarkBarButton = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStyleBordered target:self action:#selector(bookmark:)];
[bookmarkBarButton setImage:[UIImage imageNamed:#"greyBookmark.png"]];
[self.navigationItem setRightBarButtonItem:bookmarkBarButton];
bookmarkBarButton.tintColor = [UIColor colorWithRed:0.4 green:0.4 blue:0.4 alpha:0.9f];
b_bookmarked = false;
}
// Will call this method when the bookmark button is pressed
- (IBAction)bookmark:(id)sender
{
// Toggle color of bookmark icon on button
if ( (b_bookmarked = !b_bookmarked) )
{
[self.navigationItem.rightBarButtonItem setImage:[UIImage imageNamed:#"blueBookmark.png"]];
}
else
{
[self.navigationItem.rightBarButtonItem setImage:[UIImage imageNamed:#"greyBookmark.png"]];
}
// Save bookmark
}
both greyBookmark.png and blueBookmark.png have 10x26 size. Button looks narrowed when view appears. But when I click this button, button gets wider, image still changes though.
Width changes when setImage method is called in bookmark: method (gets back to default size). I tried to explicitly set the width by calling [navigationItem.rightBarButtonItem setWidth:] - doesn't help either. Before doing that, width property was set to 0 and button should have resize depending on its image size, according to documentation.
I want the rightBarButtonItem to have a const width.
Is there a reason why it gets wider after the second call to setImage?
UIImage *myImage = [UIImage imageNamed:#"greyBookmark.png"];
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setImage:myImage forState:UIControlStateNormal];
myButton.showsTouchWhenHighlighted = YES;
myButton.frame = CGRectMake(0.0, 3.0, 70,30);
[myButton addTarget:self action:#selector(BookmarkButtonPressed) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *rightbutton = [[UIBarButtonItem alloc] initWithCustomView:myButton];
self.navigationItem.rightBarButtonItem = rightbutton;
Put this method under viewDidLoad
-(void)BookmarkButtonPressed
{
//Do ur work here for Button Action
}

Removing shine effect from the buttons in a UINavigationBar

How can I remove the gloss/shine effect from the buttons on navigation bars?
If I customize the navigation bar by using a custom image the buttons are not affected, can I remove the effect from them (the line and glossing), or define a hex color code for the whole button, or even a custom image for them too?
I just went through the process of figuring this out. Basically, you need to create custom stretchable images and use them as the button's background to get rid of the shine. Replacing the back buttons in a UINavigationController is a bit tougher. For that I used a UINavigationControllerDelegate to replace the default back button with my custom button.
Here's some code:
Create a category on UIBarButtonItem that creates your custom button. Here's mine. I use this category to customize both regular bar buttons and back buttons:
#interface UIBarButtonItem (UIBarButtonItem_customBackground)
+ (id) customBarButtonWithTitle:(NSString *)title target:(id)target selector:(SEL)selector;
+ (id) customBackButtonWithTitle:(NSString *)title target:(id)target selector:(SEL)selector;
#end
#implementation UIBarButtonItem (UIBarButtonItem_customBackground)
+ (id) customButtonWithImageNamed:(NSString *)imageName selectedImageNamed:(NSString *)selectedImageName leftCapWidth:(CGFloat)leftCapWidth edgeInsets:(UIEdgeInsets)edgeInsets title:(NSString *)title target:(id)target selector:(SEL)selector {
UIButton* customButton = [UIButton buttonWithType:UIButtonTypeCustom];
[customButton addTarget:target action:selector forControlEvents:UIControlEventTouchUpInside];
customButton.titleLabel.font = [UIFont boldSystemFontOfSize:12.0f];
customButton.titleLabel.shadowColor = [UIColor colorWithRed:0.0f/255.0f green:0.0f/255.0f blue:0.0f/255.0f alpha:0.25f];
customButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.0f);
customButton.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
customButton.titleEdgeInsets = edgeInsets;
UIImage* navButtonBackgroundImage = [[UIImage imageNamed:imageName] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:0.0f];
UIImage* navButtonPressedBackgroundImage = [[UIImage imageNamed:selectedImageName] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:0.0f];
[customButton setBackgroundImage:navButtonBackgroundImage forState:UIControlStateNormal];
[customButton setTitle:title forState:UIControlStateNormal];
[customButton setBackgroundImage:navButtonPressedBackgroundImage forState:UIControlStateHighlighted];
[customButton setBackgroundImage:navButtonPressedBackgroundImage forState:UIControlStateSelected];
CGSize size = CGSizeMake(30.0f, 30.0f);
if (title != nil) {
size = [[NSString stringWithString:title] sizeWithFont:customButton.titleLabel.font];
}
customButton.frame = CGRectMake(0.0f, 0.0f, size.width + 20.0f, 30.0f);
customButton.layer.shouldRasterize = YES;
customButton.layer.rasterizationScale = [[UIScreen mainScreen] scale];
return [[[UIBarButtonItem alloc] initWithCustomView:customButton] autorelease];
}
+ (id) customBarButtonWithTitle:(NSString *)title target:(id)target selector:(SEL)selector {
return [self customButtonWithImageNamed:#"navButtonBG.png"
selectedImageNamed:#"navButtonPressedBG.png"
leftCapWidth:6.0f
edgeInsets:UIEdgeInsetsMake(0.0f, 5.0f, 0.0f, 5.0f)
title:title
target:target
selector:selector];
}
+ (id) customBackButtonWithTitle:(NSString *)title target:(id)target selector:(SEL)selector {
return [self customButtonWithImageNamed:#"backButtonBG.png"
selectedImageNamed:#"backButtonPressedBG.png"
leftCapWidth:12.0f
edgeInsets:UIEdgeInsetsMake(0.0f, 11.0f, 0.0f, 5.0f)
title:title
target:target
selector:selector];
}
#end
Add the button to your UINavigationBar
UIBarButtonItem* logoutButton = [UIBarButtonItem customBarButtonWithTitle:#"Logout" target:self selector:#selector(logout)];
self.navigationItem.rightBarButtonItem = logoutButton;
If you also want to replace the UINavigationController's back buttons, setup a UINavigationControllerDelegate and implement the willShowViewController method like so:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if([navigationController.viewControllers count ] > 1) {
UIViewController* backViewController = [navigationController.viewControllers objectAtIndex:(navigationController.viewControllers.count - 2)];
NSString* backText = backViewController.title;
UIBarButtonItem* newBackButton = [UIBarButtonItem customBackButtonWithTitle:backText target:navigationController selector:#selector(popViewControllerAnimated:)];
viewController.navigationItem.leftBarButtonItem = newBackButton;
viewController.navigationItem.hidesBackButton = YES;
}
}
Here are the stretchable images I'm using:
Back button: Pressed:
Regular button: Pressed:
For changing the back button it is not necessary to implement the delegate method uinavigationcontroller.
You only need set the hidesBAckButton property to YES after setting the desired backbutton as #Justin Gallacher explained perfectly.
self.navigationItem.leftBarButtonItem = [UIBarButtonItem customBackButtonWithTitle:#"Back" target:self.navigationController selector:#selector(popViewControllerAnimated:)];
self.navigationItem.hidesBackButton = YES;
you have to use the custom button with images without any gloss effect on the images by which you can get rid of the gloos effect of the button from navbar.

iPhone : How to set BackgroundColor of UIButton with buttonType UIButtonTypeCustom

i want to change the button color when it is clicked. I used :
[button setBackgroundColor:[UIColor redColor]];
but this shows red color only on the four corners of button not on the whole button and also when i use forState:UIControlStateNormal then the application hangs.
Is their any way to show some color on button when clicked?
[click1 setBackgroundColor:[UIColor redColor] forState:UIControlStateHighlighted];
Any help will be appreciated.
You could create an image programmatically and so have the ability to use your colors in a dynamic way:
Create a category for UIButton with this method and be sure to have QuartzCore lib imported via #import QuartzCore:
- (void)setColor:(UIColor *)color forState:(UIControlState)state
{
UIView *colorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
colorView.backgroundColor = color;
UIGraphicsBeginImageContext(colorView.bounds.size);
[colorView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setBackgroundImage:colorImage forState:state];
}
This is gonna create an image with the size of your button for your specified color and then assigning it for the wished state. Because of the usage of the backgroundImage you can still set a title for the button via the setTitle:forState: method.
This is what I do ... it's a custom subclass of a UIButton, just set the normal and highlighted colors and everything shpould work fine ;)
Header file:
//
// FTCustomButton.h
// FTLibrary
//
// Created by Ondrej Rafaj on 14/01/2013.
// Copyright (c) 2013 Fuerte International. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface FTCustomButton : UIButton
#property (nonatomic, strong, readonly) UIColor *normalColor;
#property (nonatomic, strong, readonly) UIColor *highlightedColor;
- (void)setNormalColor:(UIColor *)normalColor;
- (void)setHighlightedColor:(UIColor *)highlightedColor;
#end
This is the implementation file:
//
// FTCustomButton.m
// FTLibrary
//
// Created by Ondrej Rafaj on 14/01/2013.
// Copyright (c) 2013 Fuerte International. All rights reserved.
//
#import "FTCustomButton.h"
//*****************************************************************************
// private interface declaration
//*****************************************************************************
#interface MCSelectionButton ()
#property(nonatomic, strong, readwrite) UIColor *normalColor;
#property(nonatomic, strong, readwrite) UIColor *highlightedColor;
#end
//*****************************************************************************
// public interface implementation
//*****************************************************************************
#implementation FTCustomButton
#pragma mark Settings
- (void)setNormalColor:(UIColor *)normalColor {
[self setBackgroundColor:normalColor];
_normalColor = normalColor;
}
- (void)setHighlightedColor:(UIColor *)highlightedColor {
_highlightedColor = highlightedColor;
}
#pragma mark Actions
- (void)didTapButtonForHighlight:(UIButton *)sender {
[self setBackgroundColor:_highlightedColor];
}
- (void)didUnTapButtonForHighlight:(UIButton *)sender {
[self setBackgroundColor:_normalColor];
}
#pragma mark Initialization
- (void)setupButton {
[self addTarget:self action:#selector(didTapButtonForHighlight:) forControlEvents:UIControlEventTouchDown];
[self addTarget:self action:#selector(didUnTapButtonForHighlight:) forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:#selector(didUnTapButtonForHighlight:) forControlEvents:UIControlEventTouchUpOutside];
}
- (id)init {
self = [super init];
if (self) {
[self setupButton];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self setupButton];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupButton];
}
return self;
}
#end
Make sure the button type is custom as someone else already stated. Then doing the following will bring back those rounded corners:
[self.myButton.layer setCornerRadius:8.0f];
[self.myButton.layer setMasksToBounds:YES];
[self.myButton.layer setBorderWidth:1.0f];
[self.myButton.layer setBorderColor:[[UIColor whiteColor] CGColor]];
self.myButton.backgroundColor = [UIColor redColor];
Though, personally, I'm a big fan of gradient buttons over solid colors... also, background color doesn't have different states, whereas background images do:
[self.myButton setBackgroundImage:[UIImage imageNamed:#"gradient.png"] forState:UIControlStateNormal];
Using an image, your button will darken with selection (or you could provide a different background image per state to do something different). This won't happen with background color, the background will always stay the same, only your button label changing per state.
Completing Dima answer, I've implemented an extension in Swift:
extension UIButton {
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextFillRect(context, rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
func setBackgroundColor(color: UIColor, forUIControlState state: UIControlState) {
self.setBackgroundImage(imageWithColor(color), forState: state)
}
}
I believe a more efficient solution than any of the ones listed is to just draw the image in Core Graphics directly. You avoid having to make a UIView and calling renderInContext:, which can be pretty slow.
+ (UIImage *) imageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
You can use this in a UIImage category to create an image to use in a UIButton.
you have take a red color image for your button and then you can set it when user clicks
[yourButtonName setBackgroundImage:[UIImage imageNamed:#"yourRedButton.png"] forState:UIControlStateHighlighted];
To get a button with a single color you can set the button to custom button.
Here is my known list of available button api (you can set them in viewDidLoad after setting them as outlets).
Just import quartz and change the border radius to make it look like a button.
//highlightcolor - this changes the status for UIControlStateHighlighted
OUTLETNAME.tintColor = [UIColor orangeColor];
//borderradius *quartz
[[OUTLETNAME layer] setCornerRadius:20.0f];
//border *quartz
[[OUTLETNAME layer] setBorderWidth:5.0f];
//bordercolor
[OUTLETNAME.layer setBorderColor:[[UIColor greenColor] CGColor]];
//backgroundcolor
OUTLETNAME.backgroundColor = [UIColor blackColor];
//image
[OUTLETNAME setImage:[UIImage imageNamed:PICNAME] forState:UIControlStateNormal];
//text
[OUTLETNAME setTitle:#"TEXT" forState:UIControlStateNormal];
//fontsize
OUTLETNAME.titleLabel.font = [UIFont systemFontOfSize:36.0];
//fontcolor
OUTLETNAME.titleLabel.textColor = [UIColor blackColor];
//fontcolor
[OUTLETNAME setTitleColor:[UIColor orangeColor] forState: UIControlStateNormal];
If you want custom buttons with a gradient color you have to make a custom button class.
This blog has a glossy button class project for download.
http://didikot.com/?p=217
You have to refractor and convert to ARC to use it, I think.
This blog does the same thing but without the gloss.
http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/
#pankaj Gyani says correct
UIButton *button = [[UIButton buttonWithType:UIButtonTypeCustom] initWithFrame:CGRectMake(0, 0, 24, 24)];
[button addTarget:self action:#selector(prevButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:[UIImage imageNamed:#"IntroArrowLeft.png"] forState:UIControlStateNormal];
[self addSubview:button];
You should set UIButton's type to custom and set its image or background image properties for normal and highlighted states.
For professional and nice looking buttons that you can easily use in your apps this custom button component may also help.
You have everything correct. Just set your button type to UIButtonTypeCustom..
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(200, 8, 100, 30);
[button setTitle:#"Set up" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor greenColor]];
button.clipsToBounds = YES;
button.layer.cornerRadius = 10;
button.alpha = 0.5;
Just an update to Hendrik answer.
To work well with Auto Layout you need to set UIView frame size to button intrinsicContentSize, otherwise it will screw up layout.
- (void)setColor:(UIColor *)color forState:(UIControlState)state
{
UIView *colorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.intrinsicContentSize.width, self.intrinsicContentSize.height)];
colorView.backgroundColor = color;
UIGraphicsBeginImageContext(colorView.bounds.size);
[colorView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setBackgroundImage:colorImage forState:state];
}
Make the button type as custom.
Eg
button = [UIButton buttonWithType:UIButtonTypeCustom];
All the best.
Thanks to #Dima
Here is an updated code for swift 3.0 as UIButton extension
extension UIButton {
// thanks to #Dima http://stackoverflow.com/a/24665476/2581637 update code for swift 3
func setBackgroundColor(color: UIColor, forUIControlState state: UIControlState) {
func imageWithColor(color: UIColor) -> UIImage? {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
if let context = UIGraphicsGetCurrentContext() {
context.setFillColor(color.cgColor)
context.fill(rect)
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
self.setBackgroundImage(imageWithColor(color: color), for: state)
}
}
In .xib - set Button Type: Custom.
Set Background Color as per you want.
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
[button1 setBackgroundColor:[UIColor redColor]];

UIButton border and background image

What I Want: A border indicating if a UIButton is selected or not.
Background: I've got some UIButtons using transparent images, not text. These are toggle buttons (i.e. can be on or off).
Problem: The UIButton class gives users no indication of whether a button is selected or not unless you change something else about the button. Since the image doesn't change with the state, I'd need two of every image, one normal, one selected and set one for each state of the button. This is annoying. I thought instead I'd change the background image, but this removes the pretty border on the button, I just get a rectangle of my background image, yuck.
Possible solutions I don't like:
1) Create a background that matches the UIButton border and use that for selected. I don't like this because they wont match perfectly and I'm picky.
2) Create two images for each button, essentially identical but with a different background. This seems like unnecessary work, and since this problem is coming up repeatedly, I want a solution for the future as well.
I hope somebody's figured out a decent solution to this by now. Thanks in advance.
Since UIButton has two image layers, an image and a background image, I think you could accomplish what you want by using just two background images for all your buttons. One image shows a border and the other does not. Swap the backgrounds out when the control state changed.
//
// TabBarSingleton.h
#import <Foundation/Foundation.h>
#interface TabBarSingleton : UITabBarController <UITabBarControllerDelegate>{
NSRecursiveLock *barLock;
UIButton *Button;
UIButton *favoriteButton;
}
#property(nonatomic, retain) UIButton *Button;
#property(nonatomic, retain) UIButton *favoriteButton;
- (void) ButtonPressed;
- (void) favoriteButtonPressed;
#end
///////////////////////////////////
If you want the the borders only, then you have only one choice of using two images for the two states otherwise if your purpose is to differentiate between two states then you can do it by changing alpha a little bit of the selected button this will give the effect like toggle buttons, you can also disable the selected button and enable it again when the other button is pressed.
Hope this will give you a fair idea.
//
// TabBarSingleton.m
// Created by ArunDhwaj on 9/7/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "TabBarSingleton.h"
#implementation TabBarSingleton
#synthesize Button, favoriteButton;
- (id) init
{
if (self = [super initWithNibName: nil bundle: nil])
{
barLock = [[NSRecursiveLock alloc] init];
}
self.delegate = self;
return self;
}
+ (TabBarSingleton *) defaultBar
{
}
- (void)viewDidLoad
{
NSLog(#"TabBarSingleton: viewDidLoad");
//Hiding TabBar
self.tabBar.hidden = YES;
//Creating a UIView, its frame is same as tabBar frme
CGRect tabbarFrame = self.tabBar.frame;
UIView* customTabbarView = [[UIView alloc] initWithFrame:tabbarFrame];
UIImageView *newsFeedImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"newsfeeds_normal.png"]];
newsFeedImg.frame = CGRectOffset(newsFeedImg.frame, 0, 1);
Button = [UIButton buttonWithType:UIButtonTypeCustom];
[Button setFrame:newsFeedImg.frame];
[Button setBackgroundImage:newsFeedImg.image forState:UIControlStateNormal];
[Button setBackgroundImage:[UIImage imageNamed:#"newsfeeds_active.png"] forState:UIControlStateHighlighted];
[Button addTarget:self action:#selector(newsFeedsButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[customTabbarView addSubview:Button];
//[newsFeedImg release];
CGRect newsFeedFrame = newsFeedImg.frame;
UIImageView *favoriteImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"favorites_normal.png"]];
favoriteImg.frame = CGRectMake(newsFeedFrame.size.width, newsFeedFrame.origin.y, newsFeedFrame.size.width, newsFeedFrame.size.height);
favoriteButton = [UIButton buttonWithType:UIButtonTypeCustom];
[favoriteButton setFrame:favoriteImg.frame];
[favoriteButton setBackgroundImage:favoriteImg.image forState:UIControlStateNormal];
[favoriteButton setBackgroundImage:[UIImage imageNamed:#"favorites_active.png"] forState:UIControlStateHighlighted];
[favoriteButton addTarget:self action:#selector(favoriteButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[customTabbarView addSubview: favoriteButton];
//[favoriteImg release];
[self.view addSubview:customTabbarView ];
[self newsFeedsButtonPressed];
}
- (void) newsFeedsButtonPressed
{
NSLog(#"TabBarSingleton: newsFeedsButtonPressed");
self.selectedIndex = 0;
//Keeping Highlighted newsFeed tab
UIImageView *newsFeedImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"newsfeeds_active.png"]];
[Button setImage: newsFeedImg.image forState:UIControlStateNormal];
//Keeping normal others tab icons
UIImageView *favoriteImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"favorites_normal.png"]];
[favoriteButton setImage: favoriteImg.image forState:UIControlStateNormal];
}
- (void) favoriteButtonPressed
{
NSLog(#"TabBarSingleton: favoriteButtonPressed");
self.selectedIndex = 1;
//Keeping Highlighted newsFeed tab
UIImageView *newsFeedImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"newsfeeds_normal.png"]];
[Button setImage: newsFeedImg.image forState:UIControlStateNormal];
//Keeping normal others tab icons
UIImageView *favoriteImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"favorites_active.png"]];
[favoriteButton setImage: favoriteImg.image forState:UIControlStateNormal];
#pragma mark UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
NSLog(#"TabBarSingleton: shouldSelectViewController");
return YES;
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
NSLog(#"TabBarSingleton: didSelectViewController");
}
- (void) dealloc
{
//[barLock release];
[super dealloc];
}
#end