Dynamic height for a horizontal UIStackview - ios

I have a horizontal StackView with distribution as "fill equally". It has 3 labels.
I want one of the labels to have dynamic height.
When I set the number of number of lines to 0 for that label, it ends up breaking the constraint the spacing constraint at runtime.
All these horizontal stackviews make a one vertical stackview.
I have tried setting lower vertical hugging priority and higher resistance priority to the multiline label
Also it behaves like this in the XIB
Before changing the number of lines
After changing the number of lines

You do not need to set Content Hugging and Compression resistance property to achieve that effect.
Horizontal Stack Views: Set Alignment "Fill" & Distribution "Fill Equally"
Vertical Stack View: Set Alignment "Fill" & Distribution "Fill"
Set Label Lines to 0.
Set Top, Bottom, Leading Constraint for Vertical Stack View.

Set all constraints for UIStackView.
Update the UIStackview height constraints constant value based on UILabel text height

Not Directly answering the question rather on how to control the dynamic height of UIStackView.
Vertical Stack View. Make it free of height like no bottom constraints or no height constraints.
Contents(like view) are fixed height.
Both Alignment & Distribution of UIStackView will "fill"
now show or hide the contents then Stactview height will dynamically change.

Related

How to use auto layout so that the following layout is achieved?

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.

Create Intended UI Behavior While Also Not Getting Breaking Constraints Warnings

I have a height constraint for a horizontal stackView within a UIView that I change based on the content of a view. If the text of a label in the stackView is beyond a certain size, the constraint moves to 116.33, otherwise it is 96. This horizontal stackView is pinned to the top of this UIView.
At runtime, I get a warning of this constraint being broken, but I get the intended operation:
If I remove the constraint "Horizontal Stack View.top = top", no warnings occur, but I don't get the intended operation:
I have tried commensurately changing the height of the UIView via locationView.frame.size.height as well as by adding another constraint to the view, specifically, and adjusting that in the same way I adjust the stackView height constraint, but the resulting behavior is essentially the same.
This is the document outline:
How can I get the intended effect, and also make XCode happy?
Here is how I read your 4 conflicting constraints:
Horizontal StackView height is 96.
The Horizontal StackView and Vertical StackView are aligned at their tops.
The Horizontal StackView and Vertical StackView are aligned at their bottoms.
Vertical StackView height is >= 136.
So the heights of the StackViews are the same because of the alignment of their tops and bottoms. But they each have their own constraint setting their height.
I suggest getting rid of one of the StackView height constraints.

How to create StackView with width = largest child's width on iOS?

I want to place label to the bottom of image and align them vertically. I've tried to use StackView to achieve this. And I get this:
Is there any way to show all label's text correctly? Label text can have any length.
Constrain the label and the stack view to have equal widths.
Set the horizontal content hugging priority of the label to 249 (so it can get wider if it's narrower than the image).
Set the horizontal content compression resistance of the label to 751 (so it forces the stack view to be wider if necessary).
Result:
Don't fix the width of stackview.
Change the Alignment property of stackview to Center.
The label will grow itself with the text.

Multiline UILabel with UIScrollview using autolayout

I read many post of contentview in scrollview,but the problem is slightly different.check out the image
and i have following hierarchy
Here the label is multiline label and its fill up with too many content size.
so, the problem is
1. according to the lines of the label, height of label changes and
2. accoring to height of label, contentview height changes.
so, that it scrolls. and i want this things to be done with autolayout.
And one thing i want to mention is , i'm using ios 8.1 and xcode 6.1
The thing that you can use for your UILabel is -> Select your Label and go to Attributes Inspector and find Autoshrink set it as Minimum font size then you may describe your minimum font size.
For addition to your view, you may want to use constraints between your label and content view. So I recommend to use this documentation Auto Layout Guide. And if the documentation is too long to read you may read this answer.
You should add constraint to content-view as leading, trailing, top, bottom & equal width & equal height with scrollView. For imageView add constraint as leading, trailing, top & height. For the Label add constraint as leading, trailing, top & bottom, also check that you are setting no of lines to be zero. & For read more button add constraints as height, width, centre horizontally in container & bottom. Don't forget to add bottom constraint to button otherwise your scroll view does not understand its content size & you will get warning as ambiguous content size to scroll view.

How to simulate conditional hugging priorities in AutoLayout?

I have a UIView that contains a multiline UILabel and a UIImageView. The imageView is a square that is a specific height and width and is centered vertically in the cell, while the label is constrained to the top of the view. Here's a little illustration:
I want to be able to make the parent view expandable based on either the UILabel or the UIImageView, based on which one has the bigger height. How would I go about doing this (in Storyboard)?
You would set a bottom and top constraint for both the label and image view at a high priority. Set the constant equal to the amount of padding you'd want.
Then, on the parent view, you'll want to add a height constraint with a lower priority than the top/bottom constraints of the label and image.
That way, you guarantee padding between the label/image and their superview, which will force the superview to expand its height since its priority is lower than that of the padding.

Resources