UIButton text and image - ios

I have one UIButton. In that UIButton i have to show text and image. Image should be displayed after the text. Based on text i want to adjust the button frame.
See the image. After the text "I am a Button", i want to add a image like arrow.
UIButton *titleButton = [UIButton buttonWithType:UIButtonTypeCustom];
NSString *name = #"I am a button";
titleButton.titleLabel.text = [NSString stringWithFormat:#"%#", name];
titleButton.titleLabel.textColor = [UIColor whiteColor];
CGSize stringSize = [name sizeWithAttributes:#{NSFontAttributeName: [UIFont fontWithName:#"MyriadPro-Cond" size:24]}];
CGRect frame = CGRectMake(300, 30, stringSize.width, 30);
//frame.size.width = stringSize.width;
[titleButton setFrame:frame];
UIImageView *image = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"home.png"]];
image.frame = CGRectMake(stringSize.width, 14, 20, 13);
titleButton.imageEdgeInsets = UIEdgeInsetsMake(0, 0, stringSize.width+20, 0);
[titleButton addSubview:image];
I written code like this. But it is not working. Anyone can make it correct. Thanks in advance

You dont have to add a UIImageView over the UIButton to get this behaviour. The UIButton has itself has some properties. Set the orange image as the background image of the button, set the arrow image as the image of the button. Then adjust the insets of the title and the image of the button to move the title to the left and the arrow image to the right.
[btn setBackgroundImage:[UIImage imageNamed:#"orange_bg"] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:#"arrow"] forState:UIControlStateNormal];
[btn setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, -60, 0)];
[btn setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 125, 0)];
You have to adjust the insets according to your image and button sizes.

Related

UIButton contentVerticalAlignment doesn't center button image

I created a UIButton programmatically and set its image, but the image just won't center vertically, it's always rendered at the bottom of the button.
Here is my code:
CGFloat logoutButtonSize = self.profileItem.detailView.frame.size.height;
CGFloat logoutButtonX = self.profileItem.detailView.frame.size.width - logoutButtonSize - 8;
CGRect logoutButtonFrame = CGRectMake(logoutButtonX, 0, logoutButtonSize, logoutButtonSize);
UIButton *logoutButton = [[UIButton alloc] initWithFrame:logoutButtonFrame];
[logoutButton setImage:[UIImage imageNamed:#"logout.png"] forState:UIControlStateNormal];
logoutButton.imageView.contentMode = UIViewContentModeCenter;
logoutButton.contentMode = UIViewContentModeCenter;
[logoutButton addTarget:self
action:#selector(confirmLogout)
forControlEvents:UIControlEventTouchUpInside];
logoutButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
logoutButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
logoutButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
After setting a distinct background color for the imageView of the button I can see that it's still aligned to the bottom:
(blue = button, red = image view)
Why is it not working?
Based on your posted image, it looks like the Button itself is being clipped at the bottom, as opposed to the image not being centered vertically.
Your code:
CGRect logoutButtonFrame = CGRectMake(logoutButtonX, 0, logoutButtonSize, logoutButtonSize);
says the Button (blue rectangle) should be square. Yet in the image you posted, the blue rectangle is 120 x 88.
The bottom portion of your button is not being displayed, so it looks like your image is not centered.
By the way, you shouldn't need much of the code you are using:
// define the frame size
CGFloat logoutButtonSize = self.profileItem.detailView.frame.size.height;
CGFloat logoutButtonX = self.profileItem.detailView.frame.size.width - logoutButtonSize - 8;
CGRect logoutButtonFrame = CGRectMake(logoutButtonX, 0, logoutButtonSize, logoutButtonSize);
// instantiate the UIButton
UIButton *logoutButton = [[UIButton alloc] initWithFrame:logoutButtonFrame];
// set the image
[logoutButton setImage:[UIImage imageNamed:#"logout.png"] forState:UIControlStateNormal];
// add the button action target
[logoutButton addTarget:self
action:#selector(confirmLogout)
forControlEvents:UIControlEventTouchUpInside];
// set the resizing mask properties
logoutButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
// shouldn't need any of the following
//logoutButton.imageView.contentMode = UIViewContentModeCenter;
//logoutButton.contentMode = UIViewContentModeCenter;
//logoutButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
//logoutButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
Point 1
AFAIK, UIControlContentVerticalAlignmentCenter & contentHorizontalAlignment is for text alignment and not for image....
Point 2
UIButton *logoutButton = [[UIButton alloc] initWithFrame:logoutButtonFrame]; will create basic button (like < iOS 6) opposed to Custom button. Below is how you should have button programmatically.
UIButton * logoutButton = [UIButton buttonWithType:UIButtonTypeCustom];
[logoutButton setBackgroundImage:[UIImage imageNamed:#"logout.png"] forControlEvents:UIControlEventTouchUpInside];
[logoutButton addTarget:self action:#selector(confirmLogout) forControlEvents:UIControlEventTouchUpInside];
[logoutButton setTitle:#"" forState:UIControlStateNormal];
logoutButton.frame = CGRectMake(logoutButtonX, 0, logoutButtonSize, logoutButtonSize);
[self.view addSubview: logoutButton];
Now for image to adjust,
continueButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
You are done...
And last
Your code is not working because your UIButton is not Custom button.

UIButton title not showing when I setImage

The most common fix to this issue is "Set as background image, not normal image"
In my case I put background images on all my buttons, if it is a locked object, I add the image of a lock on top of the background image. The image looks as expected, but in that case it does not show the title of the image.
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];
if ([self.currentArray[index][6] isEqualToString:#"true"]) {
//show it
}else{
//-------------------------
//--THE PROBLEM HAPPENS IF THIS PIECE OF CODE IS EXECUTED, SPECIFICALLY setImage
//-------------------------
button.alpha = 0.5;
UIImage *locked = [UIImage imageNamed:#"locked.png"];
button.imageEdgeInsets = UIEdgeInsetsMake(15, 15, 15, 15);
[button setImage:locked forState:UIControlStateNormal];
}
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, -30, -25, -30);
[button setTitleEdgeInsets:buttonInset];
[button setTitle:name forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize: 8];
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
Here is the images without lock and with lock:
The answer is here.
Quoting: "It appears that when you put an image in the button. the text is shoved off to the right. Use the edge settings to bring it back over the image."
What you have to do is play around with the title inset in order to bring the title label back to the right position.
I would suggest having something like an extraLeftInset variable that defaults to 0 and that is set to the right value in the else branch.
The answer above suggest to use this formula [Edge inset for Title] Left = -(imageWidth * 2), so the value should be -512 since you say that the image normally is 256. It would be nicer to evaluate it at runtime inspecting the size of the image though.
Hope this helps :)
CGSize imageSize = button.imageView.image.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
0.0, - imageSize.width, 0.0, 0.0);
left side negative padding for titleLabel. Padding value must be equal to the image width

Why does the UIButton move the title label all the way to the right when I set content insets to move it to the bottom?

I'm trying to make a UIButton with an image above the text. To that end, I tried setting the edge insets of the button as so:
[button setImageEdgeInsets:UIEdgeInsetsMake(0.0f, 0.0f, 10, 0.0f)];
[button setTitleEdgeInsets:UIEdgeInsetsMake(10, 0.0, 0.0, 0.0)];
What I get is a button where the image is in the same place, and the text is squished all the way over to the side, in a space about one character wide.
How can I simply set the insets so I have the image above the text? Is that really so much to ask?
You just wrongly calculated edgeInSets.They are not there the way you think they are. Here's my test code.It did cost me a while to put image and title in the right place.
UIButton *tmp_testBtn = [[UIButton alloc] initWithFrame:CGRectMake(50, 200, 60, 40)];
tmp_testBtn.backgroundColor = [UIColor grayColor];
[tmp_testBtn setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 20, 0)];
[tmp_testBtn setImage:[UIImage imageNamed:#"France"] forState:UIControlStateNormal];
[tmp_testBtn setTitleEdgeInsets:UIEdgeInsetsMake(20, -258, 0, 0)];
[tmp_testBtn setTitle:#"testbutton" forState:UIControlStateNormal];
CGRect contentRect = [tmp_testBtn contentRectForBounds:tmp_testBtn.bounds];
NSLog(#"contenRect:%f,%f,%f,%f",contentRect.origin.x,contentRect.origin.y,contentRect.size.width,contentRect.size.height);
CGRect titleRect = [tmp_testBtn titleRectForContentRect:contentRect];
NSLog(#"titleRect:%f,%f,%f,%f",titleRect.origin.x,titleRect.origin.y,titleRect.size.width,titleRect.size.height);
CGRect imageRect = [tmp_testBtn imageRectForContentRect:contentRect];
NSLog(#"imageRect:%f,%f,%f,%f",imageRect.origin.x,imageRect.origin.y,imageRect.size.width,imageRect.size.height);
[self.view addSubview:tmp_testBtn];
[tmp_testBtn release];
By the way, I won't do like this.I prefer customize a button with a UIImageView and a UILabel added on.

UIButton Image + Text IOS

I need a UIButton with image & text. Image should be in the top & text comes under the image both should be clickable.
I see very complicated answers, all of them using code. However, if you are using Interface Builder, there is a very easy way to do this:
Select the button and set a title and an image. Note that if you set the background instead of the image then the image will be resized if it is smaller than the button.
Set the position of both items by changing the edge and insets. You could even control the alignment of both in the Control section.
You could even use the same approach by code, without creating UILabels and UIImages inside as other solutions proposed. Always Keep It Simple!
EDIT: Attached a small example having the 3 things set (title, image and background) with correct insets
I think you are looking for this solution for your problem:
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
...the rest of the customisation of the button is your duty now, and don't forget to add the button to your view.
UPDATE #1 and UPDATE #2
or, if you don't need a dynamic button you could add your button to your view in the Interface Builder and you could set the same values at there as well. it is pretty same, but here is this version as well in one simple picture.
you can also see the final result in the Interface Builder as it is on the screenshot.
Xcode-9 and Xcode-10 Apple done few changes regarding Edge Inset now, you can change it under size-inspector.
Please follow below steps:
Step-1:
Input text and select image which you want to show:
Step-2:
Select button control as per your requirement as shown in below image:
Step-3:
Now go-to size inspector and add value as per your requirement:
swift version:
var button = UIButton()
newGameButton.setTitle("Новая игра", for: .normal)
newGameButton.setImage(UIImage(named: "energi"), for: .normal)
newGameButton.backgroundColor = .blue
newGameButton.imageEdgeInsets.left = -50
In my case, I wanted to add UIImage to the right and UILabel to the left. Maybe I can achieve that by writing code (like the above mentioned), but I prefer not to write code and get it done by using the storyboard as much as possible. So this is how did it:
First, write down something in your label box and select an image that you want to show:
And that will create a button looking like this:
Next, look for Semantic and select Force Right-to-Left (If you don't specify anything, then it will show the image to the left and label to the right like the above image):
Finally, you'll see UIImage to the right and UILabel to the left:
To add space between a label and an image, go to the Size inspector and change those values depending on your requirement:
That's it!
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.imageView.image = [UIImage imageNamed:#"your image name here"];
button.titleLabel.text = #"your text here";
but following code will show label above and image in background
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.background.image = [UIImage imageNamed:#"your image name here"];
button.titleLabel.text = #"your text here";
There is no need to use label and button in same control because UIButton has UILabel and UIimageview properties.
Use this code:
UIButton *sampleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[sampleButton setFrame:CGRectMake(0, 10, 200, 52)];
[sampleButton setTitle:#"Button Title" forState:UIControlStateNormal];
[sampleButton setFont:[UIFont boldSystemFontOfSize:20]];
[sampleButton setBackgroundImage:[[UIImage imageNamed:#"redButton.png"]
stretchableImageWithLeftCapWidth:10.0 topCapHeight:0.0] forState:UIControlStateNormal];
[sampleButton addTarget:self action:#selector(buttonPressed)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:sampleButton]
You should create custom imageview for image and custom label for text and you add to your button as subviews. That's it.
UIButton *yourButton = [UIButton buttonWithType:UIButtonTypeCustom];
yourButton.backgroundColor = [UIColor greenColor];
yourButton.frame = CGRectMake(140, 40, 175, 30);
[yourButton addTarget:self action:#selector(yourButtonSelected:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:yourButton];
UIImageView *imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, yourButton.frame.size.width, yourButton.frame.size.height/2)];
imageView1.image =[UIImage imageNamed:#"images.jpg"];
[yourButton addSubview:imageView1];
UILabel *label=[[UILabel alloc] initWithFrame:CGRectMake(0, yourButton.frame.size.height/2, yourButton.frame.size.width, yourButton.frame.size.height/2)];
label.backgroundColor = [UIColor greenColor];
label.textAlignment= UITextAlignmentCenter;
label.text = #"ButtonTitle";
[yourButton addSubview:label];
For testing purpose, use yourButtonSelected: method
-(void)yourButtonSelected:(id)sender{
NSLog(#"Your Button Selected");
}
I think it will be helpful to you.
Use this code:
UIButton *button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button.imageView.frame=CGRectMake(0.0f, 0.0f, 50.0f, 44.0f);///You can replace it with your own dimensions.
UILabel *label=[[UILabel alloc] initWithFrame:CGRectMake(0.0f, 35.0f, 50.0f, 44.0f)];///You can replace it with your own dimensions.
[button addSubview:label];
I encountered the same problem, and I fix it by creating a new subclass of UIButton and overriding the layoutSubviews: method as below :
-(void)layoutSubviews {
[super layoutSubviews];
// Center image
CGPoint center = self.imageView.center;
center.x = self.frame.size.width/2;
center.y = self.imageView.frame.size.height/2;
self.imageView.center = center;
//Center text
CGRect newFrame = [self titleLabel].frame;
newFrame.origin.x = 0;
newFrame.origin.y = self.imageView.frame.size.height + 5;
newFrame.size.width = self.frame.size.width;
self.titleLabel.frame = newFrame;
self.titleLabel.textAlignment = UITextAlignmentCenter;
}
I think that the Angel García Olloqui's answer is another good solution, if you place all of them manually with interface builder but I'll keep my solution since I don't have to modify the content insets for each of my button.
Make UIImageView and UILabel, and set image and text to both of this....then Place a custom button over imageView and Label....
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"search.png"]];
imageView.frame = CGRectMake(x, y, imageView.frame.size.width, imageView.frame.size.height);
[self.view addSubview:imageView];
UILabel *yourLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y,a,b)];
yourLabel.text = #"raj";
[self.view addSubview:yourLabel];
UIButton * yourBtn=[UIButton buttonWithType:UIButtonTypeCustom];
[yourBtn setFrame:CGRectMake(x, y,c,d)];
[yourBtn addTarget:self action:#selector(#"Your Action") forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:yourBtn];
It's really simple,just add image to background of you button and give text to titlelabel of button for uicontrolstatenormal.
That's it.
[btn setBackgroundImage:[UIImage imageNamed:#"img.png"] forState:UIControlStateNormal];
[btn setContentVerticalAlignment:UIControlContentVerticalAlignmentBottom];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];

Stretch the image to fit on button depending on length of text in iOS 5

I have one image that I want to add as background image to uibutton. I want to stretch the image to fit button width. User will enter the title for button at runtime.So depending on width of text entered by user , it will strech the image. Beyond a certain width of the button , the button will not stretch further but instead the text will get truncated. Here is my code
CGSize suggestedSize = [self.strButtonTitle sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]];
NSLog(#"Widht:- %f",suggestedSize.width);
UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
customButton.frame = CGRectMake(50, 200, 75, 40);
CGRect frame = customButton.frame;
frame.size.width = suggestedSize.width;
if (frame.size.width > 75) {
frame.size.width = 75;
customButton.frame = frame;
}
else {
frame.size.width +=5;
customButton.frame = frame;
}
NSLog(#"Custom button width:- %f",customButton.frame.size.width);
UIImage *buttonImageNormal = [UIImage imageNamed:BUTTON_IMAGE];
UIImage *stretchableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[customButton setBackgroundImage:stretchableButtonImageNormal forState:UIControlStateNormal];
[customButton setTitle:self.strButtonTitle forState:UIControlStateNormal];
[customButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.view addSubview:customButton];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc]initWithCustomView:customButton];
self.navigationItem.leftBarButtonItem = barButton;
[barButton release];
My problem is , button width doesn't increase according to text entered by user.
If user enter ppppp, width doesn't increase upto 75 instead it is showing "pp...p"
Any knid of help is highly appreciated. Thanks.
The problem is in measuring the width of string. You are measuring the width of string by below way.
CGSize suggestedSize = [self.strButtonTitle sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]];
Here you are using systemFont with size as FONT_SIZE.
However you are not setting the same font to your customButton textlabel. It can be done by below way.
[customButton.titleLabel setFont:[UIFont systemFontOfSize:FONT_SIZE]];
Hope it will help.

Resources