UIButton vertical alignment doesn't work - ios

I can't figure why in the following code, the title alignment isn't remain Top.
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn2.titleLabel.font = [UIFont systemFontOfSize:53];
btn2.frame = CGRectMake(20, 20, 270, 44);
[btn2 setTitle:#"test1 test2 test3 test4 test5 test6 test7" forState:UIControlStateNormal];
[btn2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn2.titleLabel.minimumFontSize = 1.0;
btn2.titleLabel.adjustsFontSizeToFitWidth = YES;
btn2.titleLabel.numberOfLines = 1;
btn2.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;

UIButton has a very nifty property named "titleEdgeInsets" which you can use (via UIEdgeInsetsMake to reposition the top and bottom margins of the title and get the thing centered, vertically.

This behavior is due to the baselineAdjustment default property of the button's titleLabel. If you set this to UIBaselineAdjustmentNone, you should get the effect you're looking for.
btn2.titleLabel.baselineAdjustment = UIBaselineAdjustmentNone;
From the docs for UILabel:
baselineAdjustment
Controls how text baselines are adjusted when text
needs to shrink to fit in the label.
#property(nonatomic) UIBaselineAdjustment baselineAdjustment
Discussion
If the adjustsFontSizeToFitWidth property is set to YES, this property controls the behavior of the text baselines in situations where adjustment of the font size is required. The default value of this property is UIBaselineAdjustmentAlignBaselines. This property is effective only when the numberOfLines property is set to 1.
and
UIBaselineAdjustmentAlignBaselines
Adjust text relative to the position of its baseline.
Available in iOS 2.0 and later.
UIBaselineAdjustmentAlignCenters
Adjust text based relative to the center of its bounding box.
Available in iOS 2.0 and later.
UIBaselineAdjustmentNone
Adjust text relative to the top-left corner of the bounding box. This is the default adjustment.
Available in iOS 2.0 and later.
Note that the default adjustment for UILabel differs from that of a button's titleLabel.

Have a look at Content-Alignment Vertical in storyboard

I gave up trying to get this to work programmatically and just set a baseline constraint to another item. It seems to work great on IB (the content alignment property), even within a Stack View, but in code it does not work.

Related

Enlarge UIButton text?

I use Masonry library to create Auto Layout constraints programmatically. Here is my code for creating UIButton:
readNext = [UIButton buttonWithType:UIButtonTypeRoundedRect];
readNext.titleLabel.adjustsFontSizeToFitWidth = YES;
readNext.titleLabel.lineBreakMode = NSLineBreakByClipping;
[readNext setTitle:#"Читать дальше" forState:UIControlStateNormal];
[self.view addSubview:readNext];
[readNext mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(#160);
make.height.equalTo(#80);
make.right.equalTo(newsContainerView.mas_right).with.offset(-20);
make.bottom.equalTo(newsContainerView.mas_bottom).with.offset(-20);
}];
Basically its mean that i create button that aligned to right and bot of view, and width of that button is 160 points, and height is 80. However, the label text font is too small. Even when i expand width or height (or both) its no changing. How to fix that?
There is no property available to increase font size as frame size increases.
adjustsFontSizeToFitWidth is a Boolean value indicating whether the font size should be reduced in order to fit the title string into the label’s bounding rectangle.
What you can probably do is set font of titleLabel to some large value say 100 and set adjustsFontSizeToFitWidth to true. Thus that will make your font size shrink automatically so that text adjusts in the given frame size.

UIButton label text autoshrink with insets

I am using Auto Layout. I have a UIButton with a fixed height and width and a background image (a rounded square). It displays text strings of variable length (between 1 and 30 words, let's say).
I wanted to make the text autoshrink depending on string length, and to have up to 3 lines of text in my button. So I did this:
[button.titleLabel setMinimumScaleFactor:0.01];
[button.titleLabel setAdjustsFontSizeToFitWidth: YES];
[button.titleLabel setNumberOfLines:3];
[button.titleLabel setTextAlignment:NSTextAlignmentCenter];
I also set the font size to a high value like 50 in the Interface Builder. And I set the line break to "Clip".
The button's text correctly adapts to the number of characters, but it tends to go beyond the frame of the button. It does that for mid-length strings but not for huge strings and I have no idea why. I have tried to add insets to my button but it doesn't do much, only moves the overly-big text around, so I assume the font adjustment is calculated prior to the incorporation of insets.
Below a screenshot. There are 4 of those buttons, contained within the bigger blue view. The red background is the background of the button, the yellow is an image that serves as background.
I uploaded an example project on Google Drive. Use iPhone 6 Plus for simulation.
You should also set your button's titleEdgeInsets property.
For instance:
button.titleEdgeInsets = UIEdgeInsetsMake(2.0, 2.0, 2.0, 2.0);
In your project, it seems that there some layout constraints that are messing with the buttons' title label.
When adding the following constraints, it works.
UILabel *titleLabel = button.titleLabel;
NSDictionary *views = NSDictionaryOfVariableBindings(titleLabel);
[button addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[titleLabel]|"
options:kNilOptions
metrics:nil
views:views]];
Before using this solution, I suggest you first try to set your layout constraints in a simpler way if possible.

UIButton takes up its own size Autolayout

What I tried was this :-
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:btn];
btn.translatesAutoresizingMaskIntoConstraints = NO;
[btn addTarget:self action:#selector(bringUpNextViewController:)
forControlEvents:UIControlEventTouchUpInside];
btn.titleLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:14];
[btn setTitle:#"8" forState:UIControlStateNormal];
[self.view layoutIfNeeded];
NSLog(#"button size : %#", NSStringFromCGSize(btn.frame.size));
As output, I get this :
button size : {30, 29}
Then I gave setTitle string as nothing. The button width was still 30.
So why is this the case always?
I also tried giving a high compression resistance priority and high content hugging priority. Doesn't shrink to nothing.
The problem is also the fact that I want to reduce the width of the button simply based on its content, without giving any fixed width.
I could take the width of text and give the button the width, but I shouldn't be needing to do that either if the button was taking up the content width.
EDIT:
Its not the insets either which is causing the width to be 30. Ghost value.
A button is made of several subviews. It's very likely that the internal layout of a button has some default padding between the label and the button view itself.
Making a button like yours and examining the constraints shows the following:
button constraints (
"<NSContentSizeLayoutConstraint:0x8c40a60 H:[UIButton:0x8f29840(30)] Hug:250 CompressionResistance:750>",
"<NSContentSizeLayoutConstraint:0x8c55280 V:[UIButton:0x8f29840(29)] Hug:250 CompressionResistance:750>"
)
The 30 and 29 tie up with the size values you are seeing. The intrinsic content size property of the button also returns 30,29. Basically this is the minimum size for a button, in the absence of anything else.
It's not quite clear what you want or why you are bothered by this. Anything smaller will be a poor touch target, and a button with no label or image will be invisible anyway. If you add a longer title, the button will get bigger. If you add other constraints to force particular sizes, then these will override the intrinsic content size.
If you want the button to become invisible when it has no title, then you should explicitly hide it. This makes your intentions in the code much clearer and will prevent the user from accidentally hitting a button they can't really see.
I'm wondering if there is a minimum intrinsic content size for a uibutton?
Anyway, try doing...
[button invalidateIntrinsicContentSize];
Did you try [button sizeToFit];?
For custom buttons, I think that you will need to override:
- (CGSize)sizeThatFits:(CGSize)size;
Finally, if nothing other works, you can always try giving the button width from the text size like so
CGSize textsize = [yourText sizeWithFont:[UIFont fontWithName:#"HelveticaNeue" size:14]];
[button setFrame:CGRectMake(0,0,textsize.width, textsize.height)];
First define a constraint for button size in storyboard.
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *buttonSizeConst;
After that you can set it's size to whatever you want like this.
self.buttonSizeConst.constant = 65.0;
Edit: With this method you need to calculate your button width but I think you don't want to do that. You need to autoresize UIButton for it's content. For this you should give constraints like image below. It will expand to right when you change your title.

Aligning Image and Title in UiButton [duplicate]

This question already has answers here:
How can I set the title of a UIButton as left-aligned?
(15 answers)
Closed 9 years ago.
I wish to align title and image in UiButton in such a manner that the title appears on the left and the image to the extreme right.
Please note that the button is stretched so as to fill the screen horizontally.
The button layout should look something like this:-
[title .. ]
The title should have some left padding.
The image should have some right padding.
CGFloat width = self.frame.size.width;
CGFloat imageWidth = [button currentImage].size.width;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[button setTitleEdgeInsets:UIEdgeInsetsMake(0, 10, 0, 0)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, width - imageWidth - 10, 0, 0)];
However, though the title is left align, there is a lot of space on it's left. The image does not show up at all!
Following Code will work
UIButton *sectionheader=[[UIButton alloc]initWithFrame:CGRectMake(0,0,320,44)];
[sectionheader setImageEdgeInsets:UIEdgeInsetsMake(0,6,0,0)];
sectionheader.userInteractionEnabled=NO;
[sectionheader setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
// Now Create Label and addsubview to button
UILabel *lblkey=[[UILabel alloc] initWithFrame:CGRectMake(0,0,sectionheader.frame.size.width-10,sectionheader.frame.size.height)];
lblkey.accessibilityValue=#"Value";
lblkey.font=[UIFont fontWithName:themefont size:20];
lblkey.text=[creteria uppercaseString];
lblkey.backgroundColor=[UIColor clearColor];
lblkey.shadowColor = [UIColor blackColor];
lblkey.shadowOffset = CGSizeMake(0, 2);
lblkey.textAlignment=NSTextAlignmentRight;
lblkey.textColor=[UIColor whiteColor];
[sectionheader addSubview:lblkey];
And suppoce you value is going to change always and you want to make it perfect than Make UIButton class and than add above code in that category class than just call following method to change value of that label
+(void)settitle:(NSString *)value:(UIButton *)selfbutton
{
for (UILabel *valuelabel in selfbutton.subviews)
{
if ([valuelabel.accessibilityValue isEqualToString:#"Value"])
{
valuelabel.text=value;
}
}
}
I will go with alternative What you can do is add three control in one view. lets say ParentView:
1) yourButton
2) yourlable // don't use button title instead use this lable.
3) imageView
now make the ParentView autosize like below:
so as yourButton will stretched horizontally it will automatically resize ParentView.
From here on you just want to take care about position.
set yourlable to extreme left in parentView after yourButton and set autosize property to:
so it will always remain to extreme left of ParentView
And set imageView position to extreme right in parentView and set autosize property to:
so it will always remain to extreme right of ParentView
Hope it will help.
if you have added button in xib and you want to set title and image then you can do it from Attribute inspector.
in attributeinspector there is an property named Edge. By default it has set content. but there are other two options named as Title and Image.
and exactly below Inset Property is there by which you can set title and image as you want. if you select title then you can set title (move left or right as u want) likewise for image also

Long name in UIButton shortens

I have a UIButton which has a title longer than the width of the button itself. While in a UITextField I see the first part of the string (which is the one I want to show) and then three dots, on the UIButton I see the first part, then towards the center three dots and then the third part. Is there a way to fix this issue without actually cutting the string?
If the button size can't change but the titleLabel size can, you can either change the font in of the button in interface builder or in code or allow the label to adjust its font with:
button.titleLabel.adjustsFontSizeToFitWidth = YES;
If the button size can change, you could adjust that rather then the font size:
CGRect frame;
frame.origin = self.button.frame.origin;
frame.size = [self.button.titleLabel.text sizeWithFont:self.button.titleLabel.font];
self.button.frame = frame;
Alternatively, if you want the line to break at the end of the string instead of the middle, similar to how a UITextField appears, just set the lineBreakMode to NSLineBreakByTruncatingTail

Resources