I have three labels in my view:
The first label is a description and as the text will be fetched from an API it varies in length.
First question is how do I make the description label auto-adjust its height?
Second question is how do I make label 1 move relative to the height of description label and also label 2 relative to label 1.
You change the number of lines to 0 and line break mode to word wrap to make a label arbitrarily tall. You embed all three labels in a vertical stackview and set the spacing in the stackview to distribute them with equal spacing. Constrain the stackview to the top, leading and trailing edges of your view. You do not need to give it a height as it will derive its intrinsic height from the labels plus the spacing.
you should definitely take a look at autolayout:
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/
How to auto adjust height
descriptionLabel.sizeToFit()
How to auto adjust height in relation to another label
label.frame = CGFrame(x: decriptionLabel.frame.origin.x, y: descriptionLabel.frame.origin.y + descriptionLabel.frame.size.height, width: descriptionLabel.width, height:0)
label.sizeToFit()
note: You might want to add some padding to the y co-ordinate otherwise it will literally start where the description label ends.
You can do all what you want to do without writing a single line of code.
To answer your first question : For the description label set number of lines to 0;
To answer your second question You can do it with 3 simple steps using auto layout :
A) Description label: set constraints to : TOP to superview , leading space to superview , Trailing space to superview, Bottom space to label 1.
B) Label 1 : leading space to superview , Trailing space to superview, Bottom space to label 2.
C) Label 2 : leading space to superview , Trailing space to superview.
Auto layout will adjust and move desire elements based on contents.
Related
I have been facing issues horizontally aligning two UILabel and one UIImageView like this:
First label has variable width, can be truncated if long. Second label has fixed width, it should always be aligned to right of UIImageView. It should never go off screen. UIImageView is aligned to right of first label.
I have tried embedding them in horizontal UIStackView but the image + second label always aligns to end of cell. Got the same issue when trying without UIStackView.
Please help.
You can embed both label and horizontal StackView into another horizontal stack view. Then, you'd need to set the dynamic width Label's Content Compression Resistance Priority (you can find this property at the bottom of the Size Inspector), to be smaller in order for it to shrink.
Then on the container StackView (the one that contains all views), you'd need to set constrains to top, bottom, leading to 0 to the superview and the trailing to be greater than or equal to 0, for it to not take all space of the superview, but at the same time not get offset if the content is too wide.
I hope that is clear enough!
I have a vertical UIStackView whose top, leading and trailing edges are pinned to the superview and whose height is determined by its subviews.
Its arranged subviews consist of 5 horizontal UIStackViews each of which have 3 UILabels as their arranged subviews.
For each of the horizontal UIStackView, the text of the first UILabel is the heading, the text of the second UILabel is the colon and the text of the third UILabel is the info as shown in the following image
All of the UILabels have numberOfLines = 0 so that they are multiline.
I would like to create constraints using auto layout so that the following conditions are met-
The colon UILabels are all vertically aligned
The width of the info UILabels are at least 20% of parent view
The width of the info UILabels are at most 60% of parent view
If the width of all the info UILabels is less than 60% of parent view ( see 3 ), then it must shrink to the width of the widest info UILabel.
I understand how to use auto layout to create constraints to satisfy the first 3 conditions.
However, I do not understand how to create constraint to satisfy the 4th condition. I tried increasing the "Content Hugging Priority" but it shrinks the label to 20% of the parent view ( see 2 ).
Can anyone point out how to achieve this layout?
This is considerably more complex than it would appear on the surface.
The "Info" column has to be evaluated for min/max width and word-wrapping, and the "Heading" column has to be evaluated for word-wrapping based on the "Info" columns variable width... and the "Info" labels have to match widths based on the widest wrapped (or not) text.
That's a lot for auto-layout to handle.
I don't think it can be done with constraints only. The main problem being that auto-layout calculates the height of the height of the Heading labels based on the potential for the Info labels to be at their widest.
So, we can end up with this:
and the Heading label text is no longer vertically aligned to the top of the label.
The best I could come up with is to override viewDidLayoutSubviews(), using a counter which forces auto-layout to calculate the Info labels first and then the Heading labels.
As to constraint settings...
The Heading labels need nothing special - just set the number of lines to Zero to allow word-wrapping.
The "Colon" labels don't need constraints, but they do need both Horizontal Content Hugging and Compression Resistance set to 1000 (required), because we don't want them stretching or getting squeezed.
The Info labels need:
Horizontal Content Compression Resistance: 1000
Horizontal Content Hugging: 999
Width: >= its stackView Width with Multiplier 0.2
Width: <= its stackView Width with Multiplier 0.6
Width: = its stackView Width with Multiplier 0.2 and Priority: 999
and finally, the bottom 4 Info labels need Width constraint equal to the top Info label.
The horizontal stack views that make up the 5 "rows" should be set to:
Alignment: Top
Distribution: Fill
Spacing: 8 (horizontal spacing between the "columns")
The vertical stack view that holds the 5 "rows" should be set to:
Alignment: Fill
Distribution: Fill
Spacing: 10 (vertical spacing between the "rows")
I've put up a project on GitHub that demonstrates the layout -- it has 10 different "variations" of label content to show how the sizing works: https://github.com/DonMag/MutlilineVarWidthLabelColumns
you can achieve this kind of UI by using min and max constraints.
you can follow the below constraints for it.
give max width to Heading label with the relation of the screen.
give fix width to colon label
Give leading, trailing, top, bottom to info label
change Horizontal content hugging priority of info Label to 252.
please check the below images for more details.
The actual structure of my example
Constraints for Heading label
Constraints for info-label
output
If you need any help then feel free to ask again.
I have added a label on storyboard. I have given it line as 0. It's height is not static. But when there more lines then it height increased but space is added from top & bottom . I want to remove those extra space when label height is increased. I have tried using label.sizeToFit() but it align text to the left & I want text to be in centre. Only extra spacing from top & bottom should be reduced.
Here I tried following steps with SafeAreaLayout/AutoLayout to solve this problem.
For label instance in storyboard (view controller) or programmatically
Remove all (existing) constraints applied on your label.
Set all constraints (top, bottom, right left) again, with respect to its superview/adjacent UIElements.
Set number of lines = 0 (& line break mode = truncate tail)
Here is result:
Edit: Answer to your query -- my label is vertical centre to a super view
Remove Top constraint for your vertically centered label and apply constraint: Vertically in container = 0
Result with update (Vertically Center):
Edit : Make sure to decrease font size as when font becomes large , intrinsic add more space around it
contentHuggingPrioprity vertical set it to 1000
In addition to sizeToFit you could set
label.textAlignment = .center
You could also add an UIView with constaints set like the label is set right now. Inside that View you add the label with constraints to top, left and right and the height to be greater than or equal to 0.
I am working with the storyboard using auto layout.
I need a particular layout and I am not able to find a way to do it.
I have two UILabels, the first one regular and the second one bold (That's why I used two UILabels).
I need the second UILabel to be near the second. But if the second label does not have enough space to displayed, then I want it to wrap the text.
In your storyboard, set property of textfield as lines=0 give below constraints only
Top leading trailing to supverview
Height with relationship greaterthanequalto
Note: don't give bottom constraint to label
To make some part of label bold use NSAtrributeString. Don't take two labels.
Case I : If you want to adjust font size in the same line then,
Vertical space from SE CONNECTOR button
Leading constraint to superview
Trailing constraint to superview
& add code to adjust font,
yourLabel.numberOfLines = 1;
yourLabel.minimumFontSize = 8;//Keep min font size you wants
yourLabel.adjustsFontSizeToFitWidth = YES;
Case II : If you don't want to adjust font size & achieve it in multiple lines then,
yourLabel.numberOfLines = 0;
Vertical space from SE CONNECTOR button
Leading constraint to superview
Trailing constraint to superview
Give Greater than equal height constraint(& set constant to 0)
I am not sure why but I have having so much trouble with constrains and auto layout. I have the below view and I want to make it display as is shown but every single approach I take to get seems to be incorrect.
I have been following this tutorial online Auto Layout Tutorial in iOS and I am rather trying to describe my constraints. Following this technique this is what I have:
Description of my constraints.
Label:
Centered in the view
51 from the top
All images:
Must have equal height and equal width.
Are separated from the left and right by a 0 gutter.
All inner gutters separating the images are 12.
I have also included my storyboard.
storyboard link
for this you just declare height and width of the first imageview with respect ViewController use equal heights and equal widths and then change in the multiplier default it will be 1 adjust to your size then for the remaining imageviews you just give equal widths and equal heights of the first imageview.
If you want keep height and width constant , don't pin it, just use horizontal centre constraint. Pin it up using auto layout , hope this is helpful.
You are set image height and set image bottom constraint and does not set label height that you are many choice
Set your label height because you run iPhone 4 or 4s that your label doesn't display.
remove your image bottom constraint because you are set fix image height.
you image doesn't fix height that remove your set image height and all image select and set equal height constraint (all image height same).
Better You should move that four image views into a uiview(childView) .Make sure that 4 image views are the subviews of UIView.
-Add equal width and hight constraint to SuperView from the childView.
- Add multiplier value for the EqualHight and Equal Width constraints by selecting both constraints on storyboard(like 1:2.1,1:2.2).it may keep the same distance in all orientation
Add Y position and X position by trailing space and leading space, centre vertical in container.
Then Select the 4 uiimageviews and make sure they have same width and hight,after that
select 4 image views then click the pin button and check the equal width and equal hight.
Add leading ,top and trailing space for image1
[1,2]
[3,4]
add trailing and top space for image 2
add leading ,top and bottom space for image 3
add trailing ,top and bottom space for image 4,