I am trying to add a height constraint to a label so that it doesn't cut off the text that is inside:
However, when I added the height constrain to the label, a conflicting constrain error shows up prompting me to delete one of the constrains, if I just leave this message unsolved, the UI works correctly:
But what confuses me in the error is the fact that the constrain which I had just added seems to be conflicting with an un-deletable constrain height = 0 and I have no idea where is is coming from (The height = 250 is for the stack view):
I could make the error message go away by setting the priority of the label's height constrain lower than 1000, but doing this brings the 'label too small cutting off text' problem right back:
What could be causing this? What I am confused about is:
What is causing the height = 0 un-deletable constrain?
Why is that if I leave this error message unfixed, the UI works as intended?
Thank You for any help!
Tips from Paulw11 for the solution:
I solved the problem by adjusting the label's vertical compression resistance rather than setting a height. I removed the height constrain which removed the error message. In the settings for the stackview, there is a field for "Vertical Content Compression Resistance Priority" (Set to 750 here):
The problem was fixed when the "Vertical Content Compression Resistance Priority" of the label itself was set to a value higher than than that of the stackview's (Set to 1000 here):
Related
Problem:
Create horizontal UIStackView with 2 elements
Item width with "Short text 2" should be "wrap content". Item with "Long text 1" should fill all free space.
Please help to understand, how it can be created in code (Swift language)?
Step 1: Drag a StackView add left, right, top/bottom constraint to it. (ignore error for now)
Step 2: Drag two labels and add it to stackView (continue to ignore warning)
Step 3: Now you need to resolve horizontal content ambiguity so change the content hugging priority of left label to 250 while leaving the right labels content hugging priority at 251
Step 4: Now comes your question of warp content for vertical height :) Simply select the right label and set its content compression resistance to 999 while leaving left label's content compression resistance at 751
If you are wondering whats happening with content compression resistance and content hugging priority and all, please read apple docs on the same for more detail
Just to give a gist of what am doing, in iOS UILabels have implicit content size, so they take size based on content. So is Stack View. Now because StackView has to deduce its height based on two labels it has and both of them have same content compression resistance and end up having different height in order to resolve confusion it looks for further assistance from you. You do that specifying that right label resists more to change in its implicit vertical height compared to left label.
That means now stack view knows that it has to consider right labels height to adjust its height while it can override the implicit size of left label :)
Confirmation of logic:
On changing right label font stack view height automatically increased and increased the height of left label as well :)
EDIT on Comment by OP:
As OP suggested in comment that conern is width and not height, step 4 is not necessary, your problem is resolved at the end of step 3. On setting content hugging priority it self
on changing right labels content UI updates as shown below
Thats all :) Hope that helps
I'm trying to get my subtitle label to wrap, but it always remains one line with truncated text. I have it so the subtitle has a top constraint of 5px to the title/SignIn label, and 20px to the separator.
I've been working with Content Hugging and Compression Resistance but I haven't been able to figure it out.
If I remove the bottom constraint, the label becomes 3 lines as desired, but overlaps the separator (i.e. the content doesn't get pushed down).
Any help would be greatly appreciated.
Set lines to 0. Then enlarge the label to fit in the required lines of code i.e, increase the height of the label on storyboard. Then set the height constraint of the label from the pin menu to that height.
So, auto updating my project's settings and restarting Xcode/Simulator had something to do with it!
Everything seems to be working now (with the following settings for the subtitle):
Content hugging has been set to: h=251 & v=251
Content compression resistance has been set to: h=750 & v=750
Number of Lines has been set to: 0
Line Break Mode has been set to: Truncate Tail
"Bottom space to separator" constraint has been set to: Equals 20
"Top space to sign in label" constraint has been set to: Equals 5
I have two UILabels: name and description. The constraints are setup as the following:
name has left and top constraint
description has a right and top constraint
A minimum 10 pixels spacing constraint between them so that they don't overlap
When I run the program, not consistently, sometimes name is truncated and sometimes description is truncated.
Question is: Is there a way to guarantee that when running out of space alway truncate the right label?
The proper way to address this is to change the Content Hugging Priority for one of the labels. By default, this is set to 251. Just change one of the label's Content Hugging Priority to 250 or 252 depending on how you want it to be "hugged".
In code:
func setContentHuggingPriority(_ priority: UILayoutPriority,
for axis: NSLayoutConstraint.Axis)
Or interface builder:
And check out this post if you need more info about this topic: https://medium.com/#abhimuralidharan/ios-content-hugging-and-content-compression-resistance-priorities-476fb5828ef
You could try setting a minimum width constraint for the left hand label (lbl1) then connecting the constraint to an IBOutlet in your ViewController.
Then on load or willAppear or any other related action, determine the minimum width of lbl1 and set that to the constraints constant.
Then before the view appears, it should update the right hand label to the correct width without truncating the label on the left.
For reference of determining label size see this answer:
https://stackoverflow.com/a/19128912/933887
You can use this property in reducing font size is not the iss
You may use UILabel().adjustsFontSizeToFitWidth = true if you are okay with smaller font.
I'm trying to lay out the following simple UI using auto layout:
So far, I've set 5 constraints:
The left edge of the textfield is constrained to the left alignment guide
The top edge of the textfield is contained to the top alignment guide
The right edge of the label is constrained to the right alignment guide
The top edge of the label is constrained to the top alignment guide
The right edge of the textfield is constrained to be 20 points from the leading edge of the label
Based on these constraints, I would think that the width of the textbook would be determined by the size of the label, and horizontal layout for both would be implied. This is indeed how these constraints behave when I change the size of the button, but I'm still receiving the following warning in xcode:
My question is why? Width and horizontal position can be determined by the information provided, and providing additional information (like a fixed width) would only mess with the flexibility of the interface.
Well Width can't be calculated based on the constraints you applied.
Both textField and label grow and shrink based on content.
What will happen If at runtime I add much more text or increase text(content) of both the fields. Then there will be ambiguity about which field to fill full and which to trim.
So one thing need to be fixed based on that other width can be calculated.
You can add one Extra width constraint to Add Activity.
My extra width constraint would be less than or equal to the width you assign. And its priority would be greater than its leading.
Or you would want to play with content hugging priority. With changing content hugging priority one can make it possible for label not to grow.
Cocoa Autolayout: content hugging vs content compression resistance priority
If you don't want to add Extra width constraint Then increasing horizontal hugging of Add Activity to 251 (greater then textfield hugging) will resolve the ambiguous constraint issue.
I'm trying to use autolayout constraints to automatically resize a few similarly-sized buttons in a view to give the following effect:
Before resizing
Desired effect after resizing
As you can tell, I want the buttons to be of the same size and I also want the spacing between each button to be a constant 20 points. It seems pretty simple at first, so I set the following constraints:
Buttons: space from left neighbour = 20 (inclusive of left-most and right-most buttons)
Buttons: space from right neighbour = 20 (inclusive of left-most and right-most buttons)
Buttons: same width
What actually happens after resizing
When in preview or when I test run the app in my iPhone/simulator, the button resizes and doesn't even follow the same width constraint I set for it. In fact, the view containing the views also resizes to fit the new button sizes. Anyone knows how to fix this problem purely in the interface builder?
Setting:
- equal widths of all buttons
- horizontal spacing between all buttons
- leading to superview for the first button and trailing to superview for the last button
should do the job. Unless you're having problems with the superview (e.g. ScrollView missing constraints)
In the interface builder you set the spacing constraints between buttons like you described above. Then you can command-select all of them and specify the "Equal Width" constraint to apply to the selected objects.
Finally I have oblivion how to solve this problem. I've test it works like charm.
add constraints to space items with 20 units margin
add constraint to ages
now tricky part
for each item add constraint equal widths to a parent
select all this new constraints and change its properties
set multiplier to value 1:5
set constant to -24 (6 separation between items and parent edge gives 120, this multiplied by multiplier value 1:5 gives 24)
update items frames
That's it! Picture below show how it works in interface builder:
Set simulated size to "freeform" and test different widths (I sett this to 330).
This problem is seems to be because of wrong content hugging priority and content compression Resistance priority. So you should set them as low content hugging and high compression resistance (all should have same value).
Because content hugging is the property that resist a view to grow and content compression Resistance priority is to resist a view to shrink. For more information regarding these you can found this Question.