UIButton: set background of image view (without setting an image) - ios

How can I change the background color of the image view on a UIButton but without setting an image? (so that I have for example a red square next to the button text).
When I simply set mybutton.imageView.backgroundColor = UIColor.red and set the constraints of the image view to 28x28px. I do not see the red square.
Thanks.
To clarify: I want to set the background color of only the image view on of the UIButton - I do not want to color the whole button!

You tagged your question as both Swift and Objective-C, so...
In Swift, you can use this extension to create a "blank" image with a specific color:
public extension UIImage {
public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let cgImage = image?.cgImage else { return nil }
self.init(cgImage: cgImage)
}
}
Then, to add a "red square next to the button text":
let btnImage = UIImage(color: .red, size: CGSize(width: 28, height: 28))
btn.setImage(btnImage, for: .normal)
If you need to do this in Obj-C, it's the same process:
- (UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize)sz {
CGRect rect = CGRectMake(0.0f, 0.0f, sz.width, sz.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
and
UIImage *btnImage = [self imageWithColor:[UIColor redColor] andSize:CGSizeMake(28.0, 28.0)];
[_btn setImage:btnImage forState:UIControlStateNormal];
Note: make sure your UIButton type is set to Custom, or the image will be "tinted".

Use this code.
UIButton *button =[[UIButton alloc]initWithFrame:CGRectMake(85, 290,110,20)];
button.layer.cornerRadius = ROUND_BUTTON_WIDTH_HEIGHT/2.0f;
button.backgroundColor = [UIColor redColor];
button.titleLabel.textAlignment = NSTextAlignmentCenter;
button.titleLabel.font = [UIFont systemFontOfSize:11.0];
[button setTitle:#"Download" forState:UIControlStateNormal];
[button addTarget:self action:#selector(downloadBtnClicked:)forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];

You should make your own custom UIButton. Another solution would be to try tweaking the default one using the IB available options.
UIButton Image + Text IOS

UIButton *_button = [UIButton buttonWithType:UIButtonTypeCustom];
[_button setFrame:CGRectMake(0.f, 0.f, 128.f, 128.f)]; // SET the values for your wishes
[_button setCenter:CGPointMake(128.f, 128.f)]; // SET the values for your wishes
[_button setClipsToBounds:false];
[_button setBackgroundImage:[UIImage imageNamed:#"jquery-mobile-icon.png"] forState:UIControlStateNormal]; // SET the image name for your wishes
[_button setTitle:#"Button" forState:UIControlStateNormal];
[_button.titleLabel setFont:[UIFont systemFontOfSize:24.f]];
[_button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; // SET the colour for your wishes
[_button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted]; // SET the colour for your wishes
[_button setTitleEdgeInsets:UIEdgeInsetsMake(0.f, 0.f, -110.f, 0.f)]; // SET the values for your wishes
[_button addTarget:self action:#selector(buttonTouchedUpInside:) forControlEvents:UIControlEventTouchUpInside]; // you can ADD the action to the button as well like

Related

Border around text UIButton

I've a question about UIButton in iOS.
I use Apple UIButton from library and I need that it, when is pressed become "selected" and its background is blue.
I make anything and it 's working correctly, but around the "label" of title my color is more dark.
I try to set label background to clearColor but it isn't a color of label and I don't know which button subview is.
Any idea?
I use Objective-C, but if anyone has idea about Swift I understand too.
Thanks in advance
Write this code in
viewDidLoad()
self.btnDemo.layer.borderWidth = 1.0;
self.btnDemo.layer.borderColor = [UIColor grayColor].CGColor;
[self.btnDemo setTitle:#"ESTERNO" forState:UIControlStateNormal];
[self.btnDemo setTitle:#"ES" forState:UIControlStateHighlighted];
[self.btnDemo setBackgroundImage:[self imageWithColor:[UIColor clearColor]] forState:UIControlStateNormal];
[self.btnDemo setBackgroundImage:[self imageWithColor:[UIColor colorWithRed:0 green:0 blue:255 alpha:1.0]] forState:UIControlStateHighlighted];
[self.btnDemo setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.btnDemo setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
Here btnDemo is UiButton outlet
Below method for convert Color to image
- (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;
}

How to change alpha of UIButton while the buttons alpha also set

As seen on the picture I have 2 buttons with 0.5 alpha and 1 alpha. I want to change the alpha of the title in the first picture to 1. Is this possible?
So far I tried these which did not work:
button.titleLabel.alpha = 1;
[button setTitleColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1] forState:UIControlStateNormal];
UIButton *button = (UIButton *)view;
if(self.currentArray[index][2] != NULL) //before it was if (button == nil)
{
NSString *name = [[NSString alloc] initWithString:self.currentArray[index][2]];
UIImage *image = [UIImage imageNamed:self.currentArray[index][5]];
button = [UIButton buttonWithType:UIButtonTypeCustom];
int extraLeftInset = 0;
if ([self.currentArray[index][6] isEqualToString:#"true"]) {
//show it
}else if([self.currentArray[index][7] isEqualToString:#"true"]){
}else{
UIImage *locked = [UIImage imageNamed:#"fruitify_locked.png"];
button.imageEdgeInsets = UIEdgeInsetsMake(15, 15, 15, 15);
[button setImage:locked forState:UIControlStateNormal];
extraLeftInset = - 256; //size of locked
button.backgroundColor = [UIColor clearColor];
button.alpha = 0.5;
}
button.frame = CGRectMake(0.0, 0.0, 56, 56);
button.tag = index;
[button setBackgroundImage:image forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
UIEdgeInsets buttonInset = UIEdgeInsetsMake(30, -2 + extraLeftInset, -20, -2);
[button setTitleEdgeInsets:buttonInset];
[button setTitle:name forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize: 8];
button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
One way to do this would be to adjust the alpha value of your image. That can be done by passing your image to this method,
-(UIImage *)image:(UIImage *) image withAdjustedAlpha:(CGFloat) newAlpha{
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0);
[image drawAtPoint:CGPointZero blendMode:kCGBlendModeCopy alpha:newAlpha];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
The alpha setting affects a view and all it's subviews. If you set the alpha on a button, every part of the button will have that alpha value.
You have a couple of possible options.
You could create a custom subclass of UIButton that managed a UILabel that was a sibling view of the button in the view hierarchy. That would get messy in several ways however. The normal button title methods wouldn't work, and you would have to introduce your own control logic to remove the button label from the superview if the button was removed
You might also try manipulating the alpha property of the button's image view. (The buttons' imageView property is read-only, but you CAN still make changes to the attributes of the image view in that property. You would need to test to make sure that the button doesn't mess up the image view's alpha property when it swaps images for the different button states (highlighted, selected, etc.) You would probably also need to set the opaque property on the button to NO, and perhaps on the image view as well. (You'll need to experiment.)
BTW, I like you trick of offsetting the button title using setTitleEdgeInsets. I hadn't seen that before.

iOS UIButton with transparent title on white background

I have a custom UIButton with transparent background and white title.
I'm looking for a simple solution to invert it on highlight (white background and transparent title) as it is achieved on system UISegmentedControl.
Is there simpler solution than inverting alpha on snapshot used as a CALayer mask?
If not, could you tell how can I invert CALayer alpha?
You can draw the text on a CGContext using Destination Out as blend mode.
This code seems to work:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
UIFont* font = [UIFont fontWithName:#"Helvetica-Bold" size:18];
NSString* buttonText = #"BUTTON";
CGSize buttonSize = CGSizeMake(200, 50);
NSDictionary* textAttributes = #{NSFontAttributeName:font};
CGSize textSize = [buttonText sizeWithAttributes:textAttributes];
UIGraphicsBeginImageContextWithOptions(buttonSize, NO, [[UIScreen mainScreen] scale]);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, buttonSize.width, buttonSize.height)];
CGContextAddPath(ctx, path.CGPath);
CGContextFillPath(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut);
CGPoint center = CGPointMake(buttonSize.width/2-textSize.width/2, buttonSize.height/2-textSize.height/2);
[#"BUTTON" drawAtPoint:center withAttributes:textAttributes];
UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView* imgView = [[UIImageView alloc] initWithImage:viewImage];
[self.view addSubview:imgView];
}
By the way, if you want to set the UIImage in a UIButton instead of just adding it to a view:
UIButton* boton = [[UIButton alloc] initWithFrame:CGRectMake(50, 50, viewImage.size.width, viewImage.size.height)];
[boton setBackgroundColor:[UIColor clearColor]];
[boton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
boton.titleLabel.font = font;
[boton setTitle:buttonText forState:UIControlStateNormal];
[boton setImage:viewImage forState:UIControlStateHighlighted];
[self.view addSubview:boton];
You could set
-(void)viewDidload: {
[yourButton setTitleColor:(UIColor *)color
forState:UIControlStateHighlighted];
[yourButton addTarget:self
action:#selector(changeButtonBackGroundColor:)
forControlEvents:UIControlEventTouchDown];
}
-(void)changeButtonBackGroundColor:(UIButton *)button {
[button setBackgroundColor:[UIColor yourColor]];
}
remember to change it back with events: UIControlEventTouchUpInside and UIControlEventTouchOutSide :)

How to set background for UIButtons with dynamic width?

I have 3 button images named edit_category_left_up,edit_category_middle_up and edit_category_right_up
I have written code to create buttons with dynamic width now I need to set background of these button like this image below using the above 3 images
This is my current code to create dynamic buttons
-(void) addDynamicButtonsForCategories
{
_adcImage.hidden=YES;
_makeADCLabel.hidden=YES;
float x=0; float y=0; float frameHeight=_subADCView.frame.size.height;
NSString *titleString=#"";
for(int i = 0; i < 15; i++)
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
if (i<1)
{
[btn setFrame:CGRectMake(0, 0, 39, 39)];
[btn setImage:[UIImage imageNamed:#"addcategory_up.png"] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:#"addcategory_down.png"] forState:UIControlStateHighlighted];
x = x + btn.frame.size.width+10; y=y+btn.frame.origin.y;
[btn setTitle:titleString forState: UIControlStateNormal];
[btn setTag:i];
}
else
{
titleString = [titleString stringByAppendingString:[NSString stringWithFormat:#"%d",i]]; // get button title
CGSize fontSize = [titleString sizeWithFont:[UIFont systemFontOfSize:12.0]];
CGRect currentFrame = btn.frame;
CGRect buttonFrame = CGRectMake(x, y, fontSize.width + 22.0, 40);
if ((buttonFrame.origin.x+buttonFrame.size.width) >_subADCView.frame.size.width)
{
x=0;y=_subADCView.frame.size.height;
_subADCView.frame=CGRectMake(_subADCView.frame.origin.x, _subADCView.frame.origin.y, _subADCView.frame.size.width, _subADCView.frame.size.height+frameHeight);
buttonFrame = CGRectMake(x, y, fontSize.width+ 22.0, 40);
}
x = x + fontSize.width + 35.0; y=y+currentFrame.origin.y;
[btn setFrame:buttonFrame];
//I need to set the button image here
[btn setImage:[[UIImage imageNamed:#"edit_category_middle_up.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0] forState:UIControlStateNormal];
[btn setImage:[[UIImage imageNamed:#"edit_category_middle_down.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0] forState:UIControlStateHighlighted];
[btn setTitle:titleString forState: UIControlStateNormal];
[btn setTag:i];
lastButtonPosition=btn.frame.origin.y+btn.frame.size.height;
}
[self.subADCView addSubview:btn];
}
[self readjustSubviews];
}
You only need the background in a single image if you use the following technique.
UIImage *backgroundImage = [[UIImage imageNamed:#"MyImageTitle"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, leftInset, 0, rightInset)];
where leftInset is the width of unstretchable content from the left side of the image and rightInset is the width of unstretchable content from the right side of the image.
This will create an image that only stretches content inside the defined insets. This is the best way to solve this problem.
Alternatively, if you cannot possibly combine your images then you can do it like this.
UIImage *leftImage = [UIImage imageNamed:#"edit_category_left_up"];
UIImage *middleImage = [UIImage imageNamed:#"edit_category_middle_up"];
UIImage *rightImage = [UIImage imageNamed:#"edit_category_right_up"];
UIImageView *leftImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, leftImage.size.width, btn.frame.size.height)];
[leftImageView setImage:leftImage];
UIImageView *middleImageView = [[UIImageView alloc] initWithFrame:CGRectMake(leftImageView.frame.size.width, 0, btn.frame.size.width - (leftImage.size.width + rightImage.size.width), btn.frame.size.height)];
[middleImageView setImage:middleImage];
UIImageView *rightImageView = [[UIImageView alloc] initWithFrame:CGRectMake(middleImageView.frame.origin.x + middleImageView.frame.size.width, 0, rightImage.size.width, btn.frame.size.height)];
[rightImageView setImage:rightImage];
[btn addSubview:leftImageView];
[btn addSubview:middleImageView];
[btn addSubview:rightImageView];
You might need to play around with the layer the subviews are inserted at. To do that you can use one of these methods:
[btn insertSubview:view aboveSubview:otherView];
[btn insertSubview:view atIndex:someIndex];
[btn insertSubview:view belowSubview:otherView];
Try this code to combine three images
-(UIImage*)combineImages
{
UIImage *image1 = [UIImage imageNamed:#"test.png"];
UIImage *image2 = [UIImage imageNamed:#"yyu.png"];
UIImage *image3=[UIImage imageNamed:#"test.png"];
//self.imageView.image=image3;
CGSize size = CGSizeMake(image1.size.width+image2.size.width+image3.size.width, image1.size.height );
UIGraphicsBeginImageContext(size);
[image1 drawInRect:CGRectMake(0,0,image1.size.width, size.height)];
[image2 drawInRect:CGRectMake(image1.size.width,0,image2.size.width, size.height)];
[image3 drawInRect:CGRectMake(image1.size.width+image2.size.width, 0,image3.size.width,size.height)];
UIImage *finalImage =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return finalImage;
}
Are you writing for iOS7 only?
If so make a single "stretchable" image and import it into the project using an Asset Catalog.
From here you can then specify the properties of the stretchable image (i.e. cap insets etc...) in the catalog.
Then to set the background image correctly you just use...
[button setBackgroundImage:[UIImage imageNamed:#"BackgroundImage"] forState:UIControlStateNormal];
This will take the resizable/stretchable properties from the asset catalog.
Just look into this thread once. May be this is not for what you are looking, but I hope it may be helpful for you or someone else.
Build a UIImage with multiple stretchable images

UIBarButtonItem with UIImage too wide

I have a UINavigationBar and a UIToolbar (in separate views) which contain buttons and flexible space. The UIBarButtonItems' background is set like this:
bgImage = [[UIImage imageNamed:#"MyBackgroundImage.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[self setBackgroundImage:bgImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
Within the UINavigationBar, the items look just fine, optimal size and all.
BUT, within the UIToolbar, the items are always stretched to at least the width of bgImage (100 points in this case):
Any ideas why, or how to solve that? Please tell me if you need more info.
This appears to be a bug in UIToolbar. I gave it a try and the only "fix" that worked for me was to manually set the width of the UIBarButtonItem:
barButtonItem.width = 40f;
This will work fine for buttons with images, but not for text buttons as the size of the text may vary due to localization.
You can use following method for get/create image size as you want.
Use following method with specific hight and width with image
+ (UIImage*)resizeImage:(UIImage*)image withWidth:(int)width withHeight:(int)height
{
CGSize newSize = CGSizeMake(width, height);
float widthRatio = newSize.width/image.size.width;
float heightRatio = newSize.height/image.size.height;
if(widthRatio > heightRatio)
{
newSize=CGSizeMake(image.size.width*heightRatio,image.size.height*heightRatio);
}
else
{
newSize=CGSizeMake(image.size.width*widthRatio,image.size.height*widthRatio);
}
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
This method return NewImage, with specific size that you specify.
And use this Image for add on UIBarButtonItem.
Create your own button with image according to your requirement
// UIBarButtonItem+CutomBackground.h
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString *)buttonTitle target:(id)target action:(SEL)action;
// UIBarButtonItem+CutomBackground.m
#define TEXT_MARGIN 8.0f
#define ARROW_MARGIN 12.0f
#define FONT_SIZE 13.0f
#define IMAGE_HEIGHT 31.0f
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString *)buttonTitle target:(id)target action:(SEL)action
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *buttonImage = [image stretchableImageWithLeftCapWidth:15 topCapHeight:0];
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[button setTitle:buttonTitle forState:UIControlStateNormal];
[button setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
[button setContentEdgeInsets:UIEdgeInsetsMake(0.0f,0.0f,0.0f,TEXT_MARGIN)];
[button.titleLabel setFont:[UIFont fontWithName:#"Helvetica-Bold" size:FONT_SIZE]];
[button.titleLabel setShadowOffset:CGSizeMake(0.0f,-1.0f)];
CGRect buttonFrame = [button frame];
buttonFrame.size.width = [buttonTitle sizeWithFont:[button.titleLabel font]].width+ARROW_MARGIN+TEXT_MARGIN;
buttonFrame.size.height = IMAGE_HEIGHT;
[button setFrame:buttonFrame];
return [[self alloc] initWithCustomView:button];
}

Resources