Dynamically Sized UILabel Followed Directly by UIButton - ios

How can I position a UIButton right at the end of a dynamic UILabel?
Here is a screenshot of what I'm trying to achieve:

Are you using Autolayout? If so, add horizontal spacing constraint and baseline alignment constraint between the label and the button. Make sure also that numbers of lines of the label is 0.

Try
[your_label sizeToFit];
CGRect rect = your_button.frame;
rect.origin.x = CGRectGetMaxX(your_label.frame);
your_button.frame = rect;

I'd override -[UIView layoutSubviews] and do what you want there. Once you do that, the code will look something like Avt's answer. If you want the label to have multiple lines, but a constrained width, you may want to try something like
CGSize labelSize = [yourLabel sizeThatFits:CGSizeMake(someWidth, 9999)];
and use that to set the label's frame.

If you want the button to appear at the bottom of the UILabel, use constrains.

Related

How to break line of a UILabel dynamically with text?

I have a UILabel and I want to show some text in this label. I want to increase the label width at most 70% of the full screen of my device. If text length of that label doesn't fit this 70% of size then the label automatically goes to the next line as long as the text length. Every time the label length cross the 70% width of main screen then lines break as well. I have tried several ways but unable to solve yet. Please help me to solve this.
Thanks in advance;
Drag a label to your storyboard and add top and leading constraints to it.
Now select the label and control drag to the view holding the label (in your case view of ViewController) you will see the pop up and then select equal width
Now your Label's width is equal to your view's width :) That's not you want you want ur label width to be 70% of your view. So select the equal constraint of label, go to property inspector and change the multiplier to 0.7
Now your label width is 70% of your view!
But you don't want it to be 70% always. It can be at max 70% of screen, so
now change the relationship of constraint from being equal to less than or equal to.
select label and change number of lines to 0.
That's it :) have fun :)
Sample O/P:
When text is short - vs - long:
- - -
EDIT:
Not using a storyboard? Not a problem; write the same constraint programmatically and apply it to label simple enough. If you need help lemme know :)
EDIT:
As you have specified that you want to leave the gap at the beginning of each line in label you can achieve it by using Edge insets
- (void)drawTextInRect:(CGRect)rect {
UIEdgeInsets insets = {0, 5, 0, 0};
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}
You must have forgotten to increase the label's height.
The code below is for allowing the UILabel to have multiple lines:
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
Then you have to make sure the UILabel's frame has enough height to show the lines. You can achieve this by calculating the required height for the given text (NSString):
NSString *text = #"YourText";
CGFloat your70Width; // whatever your width is
CGSize constraintSize = CGSizeMake(your70Width, MAXFLOAT);
UIFont *yourLabelFont; // whatever your font is
CGRect requiredFrame = [text boundingRectWithSize:constraintSize options:NSStringDrawingUsesFontLeading attributes:#{NSFontAttributeName:yourLabelFont} context:nil];
// Keeps the old x,y coordinates and replaces only the width and height.
CGRect oldLabelFrame = label.frame;
label.frame = CGRectMake(oldLabelFrame.origin.x, oldLabelFrame.origin.y, requiredFrame.size.width, requiredFrame.size.height);
Now the label will be shown nicely in multiple lines.
To increase the height of the label according to the content if you are using storyboard. Give the label FOUR constraints (Top, Bottom, Leading, Trailing) then go to Attribute Inspector and make lines to 0 and in line break do it WORD WRAP.

How can I place a UILabel below an UIImageView such that it is always evenly placed

I have made a custom pop view which looks like this
I want to place the label of user name below the user image which is the rounded UIImageView in the given image
I want the user name to be placed evenly irrespective of the size of the text.
Like I want the name to appear like this
Align the Label content to Center.
Set a constraint from label to Image View. Horizontally center label to Image View.
As you are not using the storyboard, Below code will help you in setting the frame of label:-
UILabel *labelName;//This will be your label instance
CGFloat yAxis = 50;//This will be your image view's y axis + image view's height
[labelName setFrame:CGRectMake(0, yAxis, self.view.frame.size.width, self.view.frame.size.height)];
//Set the color/Font other properties of label as desired
[labelName setTextAlignment:NSTextAlignmentCenter];
Setting the constraint is the efficient solution.
Either you can follow the storyboard way as suggested by Mr.UB or the approach it by code way.I suggest you to use Masonry for setting the constraints if you wish to proceed by code.
And you can simply do:
[your-label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(imgView.mas_top); //with is an optional semantic filler
make.mas_centerX.equalTo(imgView.mas_centerX);
}];

Dynamically resize label based on lines of text

I am finding it surprisingly hard to resize a label containing newlines based on the quantity of lines and text. It displays fine in a large enough textview. However, I'd like the economy of sizing the label--or I'd be happy with resizing a textview--exactly.
This is the code I am using from an answer on SO but it is having no effect on the size of the label. Would appreciate any suggestions on how to make this work:
NSString *list = self.list.list;
// use font information from the UILabel to calculate the size
UITextView *view=[[UITextView alloc] initWithFrame:CGRectMake(0, 0, 280, 10)];
//make random size view
view.text=list;
CGSize size=[view sizeThatFits:CGSizeMake(280, CGFLOAT_MAX)];
// create a frame that is filled with the UILabel frame data
CGRect newFrame = _listLabel.frame;
// resizing the frame to calculated size
newFrame.size.height = size.height;
// put calculated frame into UILabel frame
_listLabel.frame = newFrame;
Why are you setting the frame of your label with reference of a newly created UITextView, it will create a useless object in your memory, to set the label frame according to your text just use this 2 line of code
lbl.numberOfLines=0;
[lbl sizeToFit];
It will make the label as large as your text.
You really should use autolayout.
Just constrain the label where you need and let UIKit do it's job.
Here an example:
I set a top space and a leading margin constraints
Then I added a width constraint and then I added some more text
As you can see the label resized itself as it knows how much text it has inside and how much space it occupies.

How can I know the height of a superview after I change one of its subview like UILabel

I change the My UILabel's text and make it become multiple lines. I guess the the superview of this label will resize after that. But how to get the new frame of the superview as soon as I change the label.text?
CGSize size = labelSuperview.size;

How can I add padding to the intrinsic content size of UILabel?

I'm using autolayout on iOS7 and I have a problem like this:
I'm putting a UILabel onto a UIView and I'm arranging my autolayout constraints so that the label's centerX = parent view's centerX. I'm not giving any width constraint to the label. When I set the label's text on runtime, the label is drawn just wide enough for the text to fit, there are no margins/paddings on the left and right sides. What I want is to have some padding on the left and right sides, so that the text doesn't begin just where the label begins. The hack to achieve this could be setting the text as #" text " but of course that's not the way to go :)
How can I achieve what I want?
You can extend UILabel and override the intrinsicContentSize by yourself. Please make sure you have set the textAlignment = NSTextAlignmentCenter as well.
-(CGSize)intrinsicContentSize{
CGSize contentSize = [super intrinsicContentSize];
return CGSizeMake(contentSize.width + 50, contentSize.height);
}
Swift 5.0
open override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
return CGSize(width: size.width + 16, height: size.height)
}
This probably only works when you only have just one line of text to display.
You can create a UILabel subclass and override intrinsicContent,
-(CGSize)intrinsicContentSize {
CGSize s = [super intrinsicContentSize];
s = CGSizeMake(s.width + 20, s.height);
return s;
}
This will add a padding of 20 points to the width. If you want your text in the middle, be sure to set the text alignment to center.
If you're using auto layout, you can set the horizontal constraints and use an NSDictionary in the metrics parameter to set this dynamically.
For instance, if you wanted to give a 10pt padding to the inner content of a UIButton, you could do something like the following:
NSDictionary *padding = #{ #"padding" : #(button.intrinsicContentSize.width + 20) };
NSArray *buttonHConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[button(==padding)]|" options:0 metrics:padding views:NSDictionaryOfVariableBindings(button)];
If you are trying to give the UILabel a different colour to its parent view, then you will need to enclose the UILabel in a UIView with the padding and the background colour you want.
If your UILabels background colour is the same as its parent view, then I don't understand the problem just use auto layout to specify how much space you want relative to the thing it is next to.

Resources