Stick three containers and a problem with iPhone X - ios

I am trying to create three containers (UI Views) as in the following example:
As you can see, in my case the TopContainer (the orange one) and the BottomContainer (the red one) have different dimensions. Also, I have a MiddleContainer (the white one) which is NOT located in the middle of the screen or in the center. In fact, the BottomContainer is a bit larger than the TopContainer.
Question: how can I keep them constrained no matter which phone my user has?
I tried to constraint the three components to the margins and between each others but it's not enough because, in that case, XCode argues that for each component the height and the width are ambiguous. Therefore I tried to maintain also the Aspect Ratio for all the three components and it seems to work, but with iPhone X (like iPhone XS) I get a ugly bottom line, so the bottomContainer doesn't fill the whole screen.
I know that there should be a "Bottom Space to" to set up for my BottomContainer in order to solve this issue but apparently I have it not, as you can see on the right side of the following screenshot:
Do you have an idea of what I am doing wrong? Do you have an alternative way to proceed?

I would solve it with a UIStackView with two UIView (orange and red). The UIStackView is set to distribute Fill Proportionally.
The orange view is the size of your orange view plus the size of the white view.
Then I'd add the white view as a child to the orange view and constrain it to the bottom of that view and with a fixed height.
To get rid of the bottom gap, set the bottom constraint to Superview instead of Safe Area.
See the screenshot for details:

As per your comment, I think this is what you can do!
Align the "middleComponent" to the center vertically, to its superview.
Set the height to it, as you want to have a fixes height there.
Then pin the "topComponent"'s bottom to the top of "middleComponent".
Pin the top of your "topComponent" to the top of the superview.
Pin the top of your "bottomComponent" to the bottom of the "middleComponent"
Pin the bottom of your "bottomComponent" to the bottom of your superview.
All these views will have have their left and right pinned to the superview's left and right.
Hope this helps

Related

Constraints to resize buttons to fit any screen - Xcode swift

I don't really understand constraints and have tried many different suggestions found online. All they seem to do is bunch everything up on top of one another or do nothing at all.
I have the following IPad application but I want it to work on any size device, mainly a IPod touch.
The page is simply two buttons that I want to remain the same no matter what screen they're on.
Any help on this appreciated.
It helps to think about points of reference that won't change with different screen sizes. Sometimes you want things on, say the top left corner so you just do constraints to the top and the left.
I'll give you two suggestions
Suggestion One
For your case, it seems like you might want to do constraints off centerY since you want them to be in the middle despite the screen size.
So I would make a constraint to "Center Vertically in Container" and then tap on the constraint and adjust it's value to negative or positive, so that way it's always X pixels above or below the centerY.
Now that's not going to be enough. it knows it's Y position but it doesn't know its height, width, or X position. So you need to add enough constraints to satisfy those.
A few examples:
X/Width: Two constraints to leading and trailing on each button OR Center horizontally and fixed width constraint. (again be careful with fixed width constraints since screen sizes can change, sometimes it's what you want though)
Height: Yeah just give it a height constraint in this case.
Note that this means no matter the screen size they'll always have the same gap between them (and maybe different gaps to the other edges).
Suggestion Two
Use a container view, either a stack view (fill, equal spacing, vertical alignment, a spacing value for gap between) or normal view.
You can make the view a fixed height based off the height and spacing between the buttons you want. Then simply center that container view horizontally and vertically on the super view.
Nonsuggestion
There are certainly other ways (like using buffer views with equal heights constraints. So you'd have an invisible view on top, a view in between and a view on bottom. and you'd give those equal heights constraints and align the buttons to the edges of the invisible views surrounding them. As long as you gave the buttons a fixed height this would work for vertical constraints) but I think these two would probably be the best.

Resize views relative to each other Xcode 6

I am building a new app using Xcode 6 and auto layout. I have only just started using auto layout and this maybe a really simple issue to fix but i have been going around in circles trying to find the right way.
I have a view played out as follows (don't have the rep to post images so have used a link instead)
http://files.parsetfss.com/48d8d860-e1c2-4671-ac59-03f46eee316b/tfss-23f6bdb8-3e5b-4ce0-b7ed-b1daf0006f33-Screen%20Shot%202015-05-22%20at%202.56.03%20pm.png
I have set constraints on the red box to keep its left,right and bottom the same distance from the superview and another to keep its height the same at all times. I then set constraints on the black and green box's keeping there top and out side edges the same distance from the superview and there bottom edges the same distance from the red box.
The aim is that the red box stays the same height and changes width with the device size and orientation, With the green and black changing height and width to fill half of the rest of the screen each and meet in the middle.
Now i have set constraints to keep the black and green the same distance from each other, and it worked as i wanted however i get warnings that the black and green boxes have ambiguous positions and widths.
The only way i have come up with to get rid of the warnings is to place a label (alpha set to 0 so it can't be seen) that is constrained to the centre of the screen then set the black and green box's contains based on the label. This works and is warning free but i am sure that this is not the best way around the issue.
So the question is how do i do this with out errors and with out placing an unnecessary hidden label.
As the view at the bottom has a fixed height...you just need to pin all edges of the all views and just need to give equal width constraints to the black and green views...just like below image...
And the output in different screens...
You need to give the black and green boxes an "equal widths" constraint. Select both boxes, and choose "Equal Widths" from the pin icon at the bottom of the canvas.
As per your requirements
1 view Black:
2 view Green:
3 view Red:
Follow these links Autolayout or Autolayout programatically
This might helps you :)

Constrains different on iPhone 4 and iPad

I have this layout when running it on an iPhone 6, which is EXACTLY what i want:
However, here it is when running on the iPhone 4S (or on the iPad):
I really can't wrap my head around this. As you can see, the above picture has the text leaving the area, and the image being "shrunken". It is as if, the first image has the image resizing itself, and in the latter the text is filling up the blank space. How do i fix this?
EDIT
Here are the constraints for the left-side image, and the right-side table:
Left image:
Right table:
And here they are selected in IB:
am not sure what you are doing with other elements but for the table and image i can suggest you those constraints. first clear all constraints of these two element and then try those.
for table in right side -
top to superview
bottom to superview
width - fixed
trailing to superview
for image on left
top to superview
bottom to superview
leading to superview
trailing to superview
put constraint values are according to your design. this will keep the right side table fixed width and resize the image to fill the rest of gap. i think this will solve your problem.
So, it's a little hard without being able to try out the layout myself, but here's what I think you need to do:
On your left image, remove the "Trailing Space To Superview" constraint.
On your right tableview, add a Width constraint, constraining the table to its current width.
This means the text in the table will stay in the same location, and the left image will grow or shrink depending on the space available.

UIView centering and resizing with constraints autolayout

I'm trying to convert my iPhone app to a universal app, but I really cannot figure out the constraints. Tried reading a whole chapter on auto layout but still I cannot manage it.
So there are 2 UIViews in my view controller, that are a square. If it's in portrait the squares will show nicely. But when I turn the iPad into landscape the squares get rectangles. Tried really everything.
The problem also, if I manage to keep them in the center and stuff, they should resize to a bit smaller size. Thought this is also possible with auto layout.
Here is the basic setup for my UIViews:
EDIT with the new suggestions:
So this is almost perfect, but it should be a square. Any idea's ?
You need the following constraints:
Vertically:
Top square pinned to superview with inset 10
Top square pinned to bottom square with inset 10
bottom square pinned to superview with inset 10
Horizontally:
Top square pinned to left edge with inset 10 (low priority)
Top square pinned to right edge with inset 10 (low priority)
Top square centered in superview
Left edge of bottom square pinned to left edge of top square
Sizes:
Top square aspect ratio of 1:1 (ctrl-drag from the view to itself to achieve this)
Bottom square width and height pinned to top square
This will make your two squares fill as much of the vertical space as possible whilst not overlapping or going outside the view.
Regarding autolayout the basic thing is to visualise how the views varies and find out to what all it needs to be attached,what all needs to be modified on the change in view layout.
Make sure the fixed values are marked as fixed in the layout
Make sure all the constraints are set by you.Automatic setting of
constraint may not work well as expected
You must read this excellent tutorial by Matthijs Hollemans

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