Center 4 images with constraints autolayout - ios

I'm new to autolayout and i'm kind of stuck on how to center these 4 images in all different devices like it looks on the images. i've tried to apply the auto configured constraints but then it will have that distance and that does not fit on all devices. So my question is what constraints do i need to apply on all different images in order to make all image centered with same distance?
Here is how my cell in storyBoard looks like:
image of the constraint options on image 1:
image in simulator:
/// MY TRY ////
Here you can see the constraints that i've added and the result?
result:

Your approach is almost correct, it simply lacks size constraints for the images.
If you want to dynamically resize the images and keep the space between them constant, put constraints on the images for the width to be >=20(or any other value, depends on your needs) and a constraint for keeping the aspect ratio. Then ctrl-drag from UIImageView1 to UIImageView2 and set a constraint for equal widths. Repeat that from UIImageView1 to UIImageView3 and from UIImageView1 to UIImageView4.
If you want the images to always keep their fixed size and dynamically sized spaces between them you need another approach:
The trick here is to place 3 empty UIViews between the UIImageViews so that it looks like this:
Set constraints to the top for all views
Set constraints to the left and right for UIImageView1 and 4
Set constraints for all UIImageViews to the same width
Set constraints for all UIViews between the UIImageViews to the same width
Set constraints for all the distances between the views to 0
Set the width constraints for the UIViews to >= 0
This way makes the empty UIViews between the UIImageViews to resize dynamically and all the same width.
I hope you get the idea.

For the first image add a leading space to superview and for the last image add a trailing space to superview and add vertical spacing between first and second, second and third, third and fourth and also set horizontally center within the container to each of the images

The objects on your storyboard require at least 4 constraints per object.
When there's orange lines around the UIImageView object like appears in your question, this means a constraint is missing, or conflicting and can often mean the image does not display at runtime like you'd expect.
In the first instance I recommend you select all objects and 'clear constraints', then start again.
Although not exactly the same, here is a link to an answer which explains the auto-layout constraints in a bit more detail. Once you understand it, auto-layout can be very powerful.
>>Link to similar auto-layout issue - iOS CustomTableViewCell: elements not aligning correctly<<
I hope this helps

If you want the images to always keep their fixed size and dynamically sized spaces between them then very easiest way first you drag the four UIView in your StoryBoard
set constrain top left right and height for all the UIViews and give the equally width to all the UIViews(drag from one UIView to another and sets its equally width repeat this work for all the UIViews).
Image about layouts
Secondly you have to drag your images set in these UIViews and sets their constrain height width and centre horizontal in container and centre vertically in container.
In last set the background colour of all UIViews default(white) you get the result it will work....i assure.
Screenshot of Xcode

Related

Problems with UIStackView constraints

I have a horizontal stack view, with an empty UIView on the left side and a label on the right side. In storyboard builder, it looks perfect (just look at the green row):
However when I run the app on Sim or device, the color view just collapses and disappears:
I have the stack view set to center alignment and proportional distribution.
If I give the color view a set width, it works well in Sim/device, however I get a warning in the interface builder, which annoys me. I assume there's a more correct way, but I don't know what that is. With set width warning:
It only allows me to delete the width=50 (the one I entered). It won't allow me to remove width=0 (not set by me, seems to be default).
Anyone have any ideas?
First, you set a proportional distribution, which tells the stackview: "Hey stackview, lay-out the views proportional". Then, you set a fixed width, so you are saying: "Hey stackview, give this a ... width". Both can not go together, since they are different.
Either make 2 stackviews, or add an UIView in to the stackview, and make that image proportional to his parent UIView.
So:
-Stackview
-UIView
-Image proportional to UIView
-Label proportional to UIView
-UIView
-Image pro...
-label...
-UIView
-Image...
-label...
And set your StackView to "Fill equally" to use this way.
Working with StackViews
A method that works is to make the strip of color beside the label an image and use UIImageView instead. StackView will then consider the UIImageView to have content and not compress it. But that will obviously cost more resources. Also to note that the images used for the strips have to be the same size or the StackView will compress them to different sizes the screen too.
Another is to set the Distribution property of the StackView to Fill Equally this will give the strip and label each half the space. It will work but may not provide the visual you are looking for.
Alternatives
By the amount of information provided, I see no requirement to use StackViews. You may instead just apply constraints that gives the strips and fixed width.
You can also try using auto layout by setting each strip to fix there distance to the leading and top while maintaining its size(actually the default settings) and the label to the same except also fixing its distance to trailing and width to scale with superview.

Static Spacing on AutoLayout

I'm currently setting up a login screen that should ultimately look something like this:
I've successfully accomplished all the constraints needed to create the desired look on all screen sizes, however, I can not seem to figure out the constraint needed to correctly align the "Don't have an account? Signup". I've designed it so the "Don't have an account?" is a UILabel, and "Signup" is a UIButton. I've just aligned these side by side.
The UILabel, "Don't have an account?", has the following constraints:
The UIButton, "Signup, has the following constraints:
These constraints seem to accomplish what they need to on screen sizes 4" and below. however the 4.7 inch, and 5.5 inch (iPads excluded), have wide spacing between the UILabel and UIButton. I've read Ray Wenderlich's tutorial on auto layout, and still can not figure out the problem (I'm new to auto layout, but I have an idea what I'm doing. I'm not just adding random constraints hoping it works).
This is what it looks like on all my targeted devices:
Notice as screen size increases, so does the gap in between the label and button. Any help is appreciated.
You are setting the leading space of the label to its superview, and you are setting the trailing space of the button to its superview. So obviously if the superview gets wider, they are going to get further apart.
So if that's not what you want, don't do that.
The actual solution to what you want to do is quite tricky. You want these two objects to behave as a group, and you want that group to be centered. There's no simple way to express that. You will need to make a group. In other words, you will need a container view, give that view an absolute width and center it, and put these two objects inside the container.
New in iOS 9, a UIStackView can help you with this.
Another approach that works is to use a couple UIViews as spacers. I sometimes prefer this to containment, but it is probably a matter of taste.
Remove the leading constraint from your UILabel.
Remove the trailing constraint from your UIButton.
Add a UIView with clear background in front of your UILabel. Set a leading constraint from this UIView to the container leading edge with constant 0. Set a trailing constraint to the UILabel with constant 0.
Similarly, add another UIView after your UIButton. Set a leading constraint from this UIView to the UIButton with constant 0. Set a trailing constraint from this UIView to the container trailing edge with constant 0.
Both UIViews will need a Y position and height. These are somewhat arbitrary so I would set Align Center-Y constraints with your UILabel, and height constraints of say 5.
Here's where the magic happens: select both UIViews and set an Equal Widths constraint. This forces the UIViews to occupy equal space on both sides.
UIStackView is overkill for this situation. Just
Put the label and button in a single UIView.
Constrain the label's left and center Y to the container view.
Constrain the button's right and center Y to the container view.
Constrain the label's right edge to the button's left edge.
Set the horizontal content hugging priority of the containing view to 1000.
Constrain the containing view's center X to its superview.
You can do it to your existing code only by setting few constraints. And this would work on all resolutions even on the iPad. You don't need to group them , i have attached the images to show the constraints that i have applied.
And for the button set this constraints
It would be shown properly on all the devices kindly have look as to how it looks on all the resolutions and also in the landscape mode of each resolution
Thanks
Omkar

Swift Center View Horizontal Ratio

I am creating a view within IB and and attempting to have 3 UILabels evenly space horizontally across the view. I came across this on SO, https://stackoverflow.com/a/30249550/4597666. I have three UILabels, each have the height and width constrained. Here is what the IB looks like:
I constrained each centered horizontally, and the first UILabel I have the multiplier 3:1, second, 3:3, third 3:5 like the post states.
When I run on my emulator, I don't get the result that I was expecting. It appears all three UILabels are centered horizontally, and the first and third are not offset.
Is there another setting that I'm missing, or another way to properly space the views evenly?
you need to make only one change.
Constraint you set is 3.CenterX to Superview.CenterX all you need to do is interchange the value so that you constraint should look like in below image.
Alternative solution. If you want to set constraints currently you have set then change the ratio from "3:5" to "5:3" and similar for all the labels.
Result:
Hope it helps you solving your problem.

Xcode Constraining UILabel vertically over a dynamic UIImageView

I am trying to constrain a label that is sitting on top a UIImageView. The ImageView keeps its aspect ratio for the different screen sizes so its length and width change according to the device.
I am running into an issue if I constrain the top of the label to the top of the image view at (for example) a constant of 58. For the lower resolution image that places the label where I want it visually. However on the higher resolution images that position is not where I want it visually. I have also tried adjusting the top constraint so that the constant is 0 and use the multiplier to adjust the position of the label. This however does not fix the problem and the label ends up at different locations on the image.
I really would not like to have to edit these constraints programmatically as I will have way more labels on different view controllers that would be a pain to program. Really hoping I can achieve this in IB.
I'm confused... why aren't you pinning a constant distance from the top of the label to the bottom of the image view?

How to center horizontally two labels?

I have pretty straightforward requirements where two labels must be centered horizontally. So, I have selected them and chose Editor->align->center horizontally. Then added top space to container constraint to both of them. I also need the labels to shrink/grow regarding content size. However, IB shows errors and several warnings. I could make the labels shrink/grow just by adding pin between them (horizontal space) but they will not be centered in that case. Here are the screenshots:
here are the errors and warnings:
UPDATE theraven gave an interesting suggestion to use dummy view for centering it horizontally and pinning two labels to it. I have removed all existing constraints, added this dummy view and center X + center Y constraints to it. Then pined two labels to it (added horizontal space constraints). However, I still get a bunch of errors and warnings:
UPDATE2 Just updating the question, but still no valid answer found. #Theraven workaround works for iPhone4, iPhone4S, iPhone5 and iPhone5S, however it's not real centering but rather a workaround. Therefore for iPhone6 and iPhone6 Plus it doesn't work as leading and trailing spaces will be fixed and won't automatically resize for larger width.
What you could do is add both labels to another view, like a container view. Then you need to center this one horizontally and add the necessary constraints.
To add the containing UIView, you can select both labels, go to Editor -> Embed In -> View.
Then you would need to add constraints to make the containing view fit the two labels. So something like this:
First Label (left one):
Leading Space to Superview
Top and bottom Space to Superview
Horizontal spacing to the next Label
Second Label:
Trailing space to superview
Top and Bottom to superview (or align top with the first one)
Then the containing view should resize as to fit both labels. Then all you need to do is add the top offset constraint for this container view and a horizontal alignment it in the parent view.
This way, the containing view will grow as much as it needs to fit both labels and the space between them and will always be centered in the parent view.
I took a screenshot of my test constraints in case it helps you more.
Hope this was what you were looking for.
To solve this use a blank UIView in between your two labels and center it horizontally. Then pin the two labels either side of the centered blank view. It is common convention to use spacer views like this in auto-layout.
I really don't like the idea of adding another view just for sake of estethic.
Another alternative is to horizontally-center the left view, and horizzontally space the right view of an amout X with the left one.
Then to give the horizontally-align contraint of the first view a negative value equal to the first view width plus half the views distance. Or use multipliers as said in a previous comment.
But this only works with fixed width views i guess.
Use centered UIStackView as a container for two labels with a spacing required.
I didn't really understand what you wish to do.
The error you get (in the first screen shot) is that you are missing constraint for the x position of the labels.
For UILabel you must have constraint both for y and for x position regarding to the container view, when you selected them both and chose Editor->align->center horizontally, you just say that label1.center.x = label2.center.x.
You still need to say where they will be in the container view, you added the top space to container, so you do have the y position, but you didn't say where the x position should be.
You said
I have pretty straightforward requirements where two labels must be centered horizontally
But where they should be in respect to their container?
thanks
Using spacer views is the best possible solution I could figure out, even though it looks ugly for the developer. The user wouldn't even know what's going on behind the scenes and once you have the spacer UIView, you can always reuse it.

Resources