sizeToFit is placing padding around very short strings - ios

I have a UIButton on which I call sizeToFit after settings its title. In cases where the title text is very short (probably < 20pt), the button is taking on a few points of padding on the left and right. For anything longer, the padding disappears. It is as if the button has an internal minimum width that is respected when sizeToFit is called. Does anyone know how to prevent this padding?

This works, Just change the string to whatever and and enjoy the resizing miracle.
NSString * helloKitty = #"I love cats";
UIButton * ss = [UIButton buttonWithType:UIButtonTypeCustom];
[ss setTitle:helloKitty forState:UIControlStateNormal];
[[ss titleLabel] setFont:[UIFont systemFontOfSize:14]];
[ss setBackgroundColor:[UIColor pink] forState:UIControlStateNormal];
CGSize strSizer = [helloKitty sizeWithAttributes:#{NSForegroundColorAttributeName:[UIColor blackColor],
NSFontAttributeName:[UIFont systemFontOfSize:14]}];
[ss setFrame:CGRectMake(100,200,strSizer.width, strSizer.height)];
[self.view addSubview:ss];

Related

UIButton title clipped

I have a custom button with the font.
customButtonSynchronize = [UIButton buttonWithType:UIButtonTypeCustom];
customButtonSynchronize.frame=CGRectMake(578, 27.5, 91, 29) ;
[customButtonSynchronize setBackgroundImage:[UIImage imageNamed:#"synchronize.png"]
forState:UIControlStateNormal];
customButtonSynchronize.titleLabel.font = [UIFont fontWithName:#"HelveticaLTStd-Roman" size:14.0f];
[customButtonSynchronize setTitle:#"Sincronizzare" forState:UIControlStateNormal];
/////HERE//////////
customButtonSynchronize.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
customButtonSynchronize.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
customButtonSynchronize.contentEdgeInsets = UIEdgeInsetsMake(8, 0, 0, 0);
customButtonSynchronize.backgroundColor=[UIColor clearColor];
[customButtonSynchronize addTarget:self action:#selector(synchronizeDB:) forControlEvents:UIControlEventTouchUpInside];
But the text above seems to be "Cut off" a little.See the top of "S".
I dont want to change frame of button,size of the font.Changing the inset DOESNOT avoid the problem. Is it a simulator bug or problem with helvetica font? Any work around?
set uibutton title to nil then create label with text and add subview to uibutton thats all, now it will display text correctly as you required

Switched from UILabel to UIButton. Text disappears

I just switched from a UILabel to UIButton, intending to use the button's titleLabel property to display the information formerly displayed in the label replaced by the button.
Problem is, the text doesn't show up. I've checked to see if the button itself (normally with a transparent background, changed to red to check) is appearing, and it is, but the text isn't there. Here's a sample of the relevant code, which is identical to the original (working) code from the label, changing only lines like:
UILabel *firstLabel;
(...)
firstLabel.textColor = [UIColor blackColor];
to:
UIButton *firstLabel;
(...)
firstLabel.titleLabel.textColor = [UIColor blackColor];
Here's a full chunk for clarity:
firstLabel.frame = CGRectMake(thisRiser.bounds.origin.x, thisRiser.frame.size.height -focusBarEndHeight - 55, barWidth, 60);
firstLabel.backgroundColor = [UIColor clearColor];
firstLabel.titleLabel.textColor = [UIColor blackColor];
firstLabel.titleLabel.text = [NSString stringWithFormat:#"%#\n%.2f%%\nTime--%#",focusItemName,focusItemPercent,actualDurationFocusItem];
[firstLabel.titleLabel setFont:[UIFont boldSystemFontOfSize:12]];
firstLabel.titleLabel.numberOfLines = 0;
firstLabel.titleLabel.textAlignment = NSTextAlignmentCenter;
[firstLabel setHidden:NO];
What am I missing? Any ideas?
Thanks!
UPDATE --
This may be related to a known bug!
Many thanks to the responders below. I implemented the first recommended fix, which resolved my initial problem, so my text now appears in the label. However, the UIControlStateHighlighted and UIControlStateSelected don't work.
For example, this code produces no discernible effect to the text when clicked:
firstLabel.backgroundColor = [UIColor clearColor];
[firstLabel setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[firstLabel setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
[firstLabel setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
After searching around SO for a while, I'm coming to the conclusion that there is a bug (at least in iOS 7) that prevents proper functioning of these methods. Unfortunately, I'm not smart enough to provide more detailed information, but plenty of recent posts point to a major problem in this area of UIControl.
I'll be ecstatic to be proven wrong, because I'd like to use this functionality.
UIButton responds to different messages, you can use the button state to change its title.
You can set the title like this;
UIButton *button = [UIButton buttonWithType: UIButtonTypeCustom];
[button setTitle:#"Title goes here" forState:UIControlStateNormal];
See Control State: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIControl_Class/Reference/Reference.html#//apple_ref/c/tdef/UIControlState
To set a title in an UIButton, you have to init the button:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, 60, 20)];
and then use:
[button setTitle:#"text" forState:UIControlStateNormal];
where you must specific the control state (highlighted, selected, etc.)
try for example,
UIButton *firstLabel = [UIButton buttonWithType:UIButtonTypeCustom];
firstLabel.frame = CGRectMake(0, 60, 100, 50); //set the frame
[firstLabel setTitle:#"Hello" forState:UIControlStateNormal];
[firstLabel setBackgroundColor:[UIColor redColor]];//for test
[firstLabel setTitleColor:[UIColor greenColor] forState:UIControlStateNormal]; //it will always displays green for normal
[firstLabel setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];//if u touch it text changed to white instantly
[firstLabel setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];//if touch it and hold it shows white color

Positioning UILabel just after text ending of UIButton?

I have a view which has a label on extreme left, then a button with username and then his comment after the button on the right. What I want to do is to position Label where text of UIButton is ending. In this case, if username is long or short, comment will start without any space between the username button and comment label. I am currently doing hard coded like this, how can I achieve dynamic position of UILabel depending upon size of text of UIButtion?, PfButton is subclass of UIButton Thanks
PfButton *button = [PfButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:name forState:UIControlStateNormal];
[button setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[button setContentEdgeInsets:UIEdgeInsetsMake(0, 13, 0, 0)];
[button setObjectId:objId];
[button addTarget:self action:#selector(profilePhotoButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[button setFrame:CGRectMake(30, -7, 130, 20)];
[[button titleLabel] setTextAlignment:NSTextAlignmentLeft];
[view addSubview:button];
UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(160, -7, 150, 20)];
[messageLabel setFont:[UIFont systemFontOfSize:15]];
[messageLabel setText:msg];
[messageLabel setTextAlignment:NSTextAlignmentLeft];
[view addSubview:messageLabel];
[messageLabel release];
sizeToFit doesn't work well if you want to have your button be wider than the label, or if you change one of the many sizing properties on the button. A better solution is to simply translate the titleLabel's coordinate system to the buttons superview.
CGRect buttonTitleFrame = button.titleLabel.frame;
CGRect convertedRect = [button convertRect:button.titleLabel.frame toView:button.superview];
CGFloat xForLabel = convertedRect.origin.x + buttonTitleFrame.size.width;
CGRect currentLabelFrame = label.frame;
CGRect labelFrame = CGRectMake(xForLabel, currentLabelFrame.origin.y, currentLabelFrame.size.width, currentLabelFrame.size.height);
label.frame = labelFrame;
The second line is the key one here. You ask the button to convert a rectangle that is within it (in this case the title labels) to what it would be in another view (in this case the buttons superview, which is probably your view controllers self.view).
Line 3 takes the translated origin and adds the labels exact width, and 5 uses the values from the labels frame except the x, which is our calculated value.
Got it to work by using
[button sizeToFit];
It gave me the exact frame, then calculated the position of label by taking into account button's x position and width

UIButton - Lead Text with Icon

I am trying to figure out a solution to creating a UIButton, with centred text which has a UIImage (icon) leading the text, so its sites just in front of the button title.
I, however am struggling to think up a way of doing this as you cannot retrieve the position of the text. Any thoughts? This must be a fairly common thing to do.
Use this code
UIButton *scoreButton=[UIButton buttonWithType:UIButtonTypeCustom];
scoreButton.frame=CGRectMake(0,0,100, 100);
//scoreButton.contentEdgeInsets=UIEdgeInsetsMake(0, 0, 0, 2);
scoreButton.contentHorizontalAlignment=UIControlContentHorizontalAlignmentLeft;
scoreButton.titleLabel.font=[UIFont boldSystemFontOfSize:13];
[scoreButton setTitleColor:[UIColor colorWithRed:0.9411 green:0.5647 blue:.2916 alpha:YES] forState:UIControlStateNormal];
[scoreButton addTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
UIImageView *scoreButtonImageView=[[UIImageView alloc]init];
scoreButtonImageView.frame=CGRectMake(0,35,30 ,30);
scoreButtonImageView.image=[UIImage imageNamed:#"leaderboard_score_button.png"];
[scoreButton addSubview:scoreButtonImageView];
Use UIEdgeInsetsMake to set your text start and end points.
In this way your image will be on the extreme left hand side and you can write text after the image
Create a UIView subclass that has a UIImageView and UILabel. Position the label to the right of the image view within this view. Add this view to your button and position it horizontally and vertically centred.
I think , it will help you. Always careful with setImage: and setBackgroundImage:
UIButton *yourBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[yourBtn setBackgroundImage:bgImage forState:UIControlStateNormal];
[yourBtn setBackgroundImage:bgImage forState:UIControlStateHighlighted];
[yourBtn setTitle:titleString forState:UIControlStateNormal];
Use following method :
UIImageView *yourPlusSign = [UIImageView alloc]initWithImage:[UIImage imageNamed:#"yourPlusSignImageTitle"];
yourPlusSign.frame = CGRectMake(x, y, width, height);//choose values that fit properly inside the frame of your baseButton
//or grab the width and height of yourBaseButton and change accordingly
yourPlusButton.contentMode=UIViewContentModeScaleAspectFill;//or whichever mode works best for you
[yourBaseButton addSubview:yourPlusSign];
Here is Ref : Add an image inside UIButton as an accesory
you can also subclass UIButton it is a better way to do it.
If you use font images like me you can do it with a NSParagraphStyle
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSTextAlignmentCenter];
UIFont *font1 = [UIFont fontWithName:#"Avenir-Roman" size:14.0];
UIFont *font2 = [UIFont fontWithName:#"Icon-Moon" size:12.0];
NSDictionary *fontSyle1 = #{NSUnderlineStyleAttributeName:#(NSUnderlineStyleNone),
NSFontAttributeName:font1,
NSParagraphStyleAttributeName:style};
NSDictionary *fontStyle2 = #{NSUnderlineStyleAttributeName:#(NSUnderlineStyleNone),
NSFontAttributeName:font2,
NSParagraphStyleAttributeName:style};
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:[IcoMoon iconString:k12_ADD_NOTE] attributes:fontStyle2]];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:#" Add Note" attributes:fontStyle1]];
[_addNewBtn setAttributedTitle:attString forState:UIControlStateNormal];
[[_addNewBtn titleLabel] setNumberOfLines:0];
_addNewBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;
_addNewBtn.layer.borderWidth = 1;
[_addNewBtn setBackgroundColor:[UIColor whiteColor]];
[_addNewBtn setTintColor:[UIColor darkGrayColor]];
This where you can get icon fonts https://icomoon.io/
This part is part of a way to convert char's to strings
[IcoMoon iconString:k12_ADD_NOTE]
you can find out more by going to https://github.com/sebastienwindal/IOSIcoMoon

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];

Resources