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.
Related
I am new to iOS Dev and Xcode.
I was trying to practice Auto Layouts in Xcode.
So I was faced with a problem where I wanted to have my score label 20 points from the left side of stack view. So I embedded my label in a UIview element and was able to constraint it to 20 points from left. However, it seems like my UIview element's size has been locked and I am unable to reduce its size.
I want my view element to take same height as my score label which is like 71.5 points but it turns out that minimum height that can be reached for this UIview element is 333.5 as you can see in the image above.
So, how can I reduce its height and did I do anything wrong?
----------- Updated: Here are the constraints -----------
You can delete the MyView.top = top constraint.
Your "Score:" label already has top, leading and trailing constraints to MyView, so add a bottom = Score:.bottom constraint. That will tell the bottom of the white MyView to stick to the bottom of the label.
You may also need to set the Score label's Content Hugging vertical priority to Required (1000).
That should do it.
I have been working on improving myself concerning Auto Layout and creating design.
I have read a lot about constraints priority, compression resistance and hugging priority but also intrinsic content size.
After re-creating almost all xib/storyboard files in my project, I have been struggling with a simple design of a custom UICollectionViewCell.
Here is the required design :
But I can't seem to create appropriate constraints in order to handle all screen resolution (specifically iPhone 5).
Here is what I have done :
I have create 2 separated views, title view at the top, and contentView.
Concerning the Blue and Gray Views :
Now in order to always have approximately same look on different screen device, I added a constraint equal height between the blue view and the contentView (white view), with constant 1:3. Which means the blue view will always be 1/3 of the parent white view.
And for the gray view, I have added an equalHeight constraint with the blue view equal to 1:2.
The UILabel and the 2 UIImage Views:
Now the fun part begin, I have setup trailing, top and bottom constraint for the UILabel in the blue view, and same but leading for the big ImageView which is outside, with horizontal constraints between the UILabel and the alert icon Image View, and horizontal constraint between the 2 Images Views.
Now I know I have auto layout constraint ambiguity because it doesn't know which element to compress or to clip.
EDIT : So I changed the content hugging priority of the UILabel to 1000 and now I have all my 3 elements but on an iPhone 5 the result is a catastrophe.
EDIT : Here is a global image with all the constraints. It doesn't look good on iPhone 5.
You have a constraint ambiguity because you have to set width/height constraints for the alertImageView and warningImageView, beside set contentHugging priority horizontal of the label to 1000
Also it's possible to create H spacing between the alertView and the warningView despite not being on the same container.
I have a cell in which I place four buttons and four labels. Each button gets assigned a picture with width 50 and height 50. Furthermore, all buttons have a corresponding label describing what they're intended for.
My objective is to have the buttons and labels resize to keep the buttons' and labels' aspect ration intact while the screen dimension changes on different devices. I have been playing with auto layout changing the hugging and compression to achieve this but haven't been successful yet. Any help would be much appreciated...
I think you should take a look at a UIStackView, because this seems exactly as a use case for stack. Just put each pair button/label in a stack, and then all four pairs into a horizontal stack, which you constraint to the cell itself. You should be able to handle all you need just by configuring the stack’s properties (axis, distribution, alignment, spacing).
Embed your button and label into a view. Set the width of this view equal widths to content view and change the multiplier value to 1:4. This will adjust the widths of the views according to superview. Also, set the top and bottom constraint to 0 for this view.
Provide center align y-axis constraint to button after setting the width and height constraint to 50. Set its top constraint to a value you deem fit.
Set labels's leading and trailing constraint to a value like 8. Choose center alignment for text. Also, provide top constraint to buttona nd bottom to its superview.
Copy the view and paste to create the three views and provide them equal widths constraint to the first view. Also, provide their leading, trailing, top and bottom constraints.
Here are a fast tutorial in how to achieve that:
1-
2- completion of the first Gif:
Note you can achieve the same output using a UIStackView
Following image shows the design for the two UIView. The one in green should always be 20% and the yellow should always be 80%, in land scape or portrait.
I am missing on some constraint or content hugging change, so trying to fix.
Note: Content hugging and compression priority has default values.
You don't want to have a fixed height of 212 for your top view. You want it to be 20% of it's super view.
You should delete your top view's height constraint of 212.
Select both your top view and its super view.
Add an equal height constraint.
Double click on that constraint and open it's size inspector.
Change multiplier to 0.2
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.