Resize Uiview with Auto Layout - ios

Right now I'm studying auto layout and I'm facing a problem that I can't solve.
I have a view that loads correctly in a 4 inch device (left view) and I'm trying to adapt it for a 3.5 inch device, to make exactly like the right view on the image:
The only difference is that the green, orange, black and pink views should shrink a little to maintain the same size for the two above views.
My problem is that I can't figure out a way to do that using the constraints.
This is what happens with the constraints that I already have:
I already tried to pin the bottom space to superview of the black and pink views to 0 hopping that the views would shrink to fit the screen, but this does not work and give me a lot of warnings on Xcode.

You need equal-height constraints between the green and black views, and between the orange and pink views.
Let's construct your layout from scratch. It's usually easier to set up constraints if you make your views smaller than you want, and edit the constraint constants to size them up. So we start with five views:
This layout of the views here is important! Note that the orange view, for example, is strictly to the right of the green view. This means if I ask Xcode to create a constraint from the green view's trailing edge to its nearest neighbor, that neighbor is the orange view, not the superview.
It is helpful to name the views in the document outline. To name one, click its entry in the outline, press return, then type the name:
Select Blue. Give it constraints with constant 0 on the top, leading, and trailing edges, and a height constraint:
If you update its frame (as I did in the dialog), Xcode will lay it out like this:
Next, select Green. Give it constraints with constant 0 on all four edges. Top should go to Blue, leading should go to superview, trailing should go to Orange, and bottom should go to Black. You can check which view is on the other end of the constraint by clicking the disclosure triangle:
Don't update Green's frame yet! It should look like this:
Next, do the same for Orange, Black, and Pink.
Once you've created the edge constraints for all four of the bottom views, select all four of those views (Green, Orange, Black, and Pink). It should look like this:
With all four selected, create equal-width and equal-height constraints:
Note that this is overkill. We don't really need the equal-height constraints between the left and right columns, and we don't need the equal-width constraints between the top and bottom rows. But this answer is already a mile long and it's much shorter to create all the equal-size constraints in one action.
Now it should look even messier:
Select the top-level view or the view controller and choose Update All Frames in View Controller:
Xcode should lay out the views like this:
If you click the form factor toggle button, Xcode should lay out the views like this:
I've uploaded the final storyboard to this gist.

Related

Stick three containers and a problem with iPhone X

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

How do I properly set my constraints for an adaptive layout?

I am extremely bad at creating layouts for multiple screen orientations. All along I've been using suggested constraints on Auto-Layout but sometimes they don't work as desired. I've been trying to learn how set up my layouts properly by reading and watching tutorials, but I still cannot understand how exactly constraints work!
What I am trying to do is to make the button widths equally like so in iPhone 7:
But on other devices such as iPhone 4S, the second button width shrinks, which is not what I wanted:
Can someone please explain to me how constraints work in layman terms? I do not understand things like:
Leading/Trailing Space
Constrain to margins
Equal Widths and Heights
Top, Bottom, Baseline etc. (What do they even mean?)
Here's how to make two equal-width buttons:
Create two buttons
Add a vertical position constraint to each button. For example, you could position them in the center of the parent view using the "Align->Vertically in Container" function (in the lower-lefthand corner of the interface builder window)
Select both buttons. Add an equal width constraint between them using "Add New Constraints->Equal Widths"
Constrain the left edge of the left button to the leading edge of the parent view
Constrain the right edge of the left button to the left edge of the right button. Add space between the buttons using the "Constant" property of the constraint you created.
Constrain the right edge of the right button to the right edge of the parent view
Hope that helps! 😀

Xcode pin bottom constraint doesnt work

Why the pin constraint doesnt work? I have no constraints, and I want to pin one view to bottom of main view, so I select the child view, then I click the icon from "w:Any h:Any row" in Interface Builder bottom right (Pin), then i click the bottom "I" to create bottom constraint, but if I resize the controller view (in design mode) the view is not moved but something like this appears: (The red line with number - instead of moving the blue view to bottom).
I have pinned it to "bottom layout guide". I also tried to pin it to "view" from dropdown while pinning, but that doesnt work too.
If I look on the "Issue navigator" there is only warning saying "Position and size are ambigious for View"
Without any other other constraints there is no way for Xcode to know what you want to do with the view, all it knows is that you want the bottom of your subview to stay 99pts away from the bottom of the superview, but doesn't know what to do with the top, left, or right edges.
Try adding constraints for the remaining 3 edges, it can be as simple as setting the width and height (the options under the bottom edge in your screenshot), or something more complex depending on what you want to achieve.
You need to define the position of view properly. So that constraints can define position and size of the object.
Like in your case you have only provided constraint from the bottom, which will not be sufficient to define position. So you need to define either Height and Width constraints or top, left and right constraints.
And as long as long red line is being shown keep adding constraints.

creating complex layout in storyboard

I'm trying to create a complex user interface in storyboards. All I get is a bunch of errors and I do not know exactly how to resolve them, because suggested constraints are not appropriate. This is link to my project: link. Final layout should look similar to that in an image:
Short version: layout should look like the one in the picture on any screen size. Image View and coloured view should both become bigger on bigger screens. All image view should be the same size.
Long version:
All image view should be the same size.
The big white view will should always take the upper half of screen. I know how to do that. The red view should appear exactly in center of its superview,the big white view.
Two blue view should have exactly the same width as the red one. Width of those 3 view should match the height of the 2 green views. Meaning, the taller the screen is(taller screen means higher green views), the wider the space between ImageViews(those who has Image word in it, that basically means wider blue and red views).
The white views at the left and right fill the space form left image view to left margin and right image view to right margin.
All views are pined with 0 to its first neighbour. Blue and red are pined horizontally, green views are pined vertically. Also the bottom and upper image view are pined to bottom and top of superview(big white view) respectively.
I do not want to set the height and width constraint on image views, because they should be detremined at runtime.
I would really appreciate if anyone here could help me out!
I have uploaded the solution on GithubRepo, you can have a look.
1) "Also the bottom and upper image view are pined to bottom and top of superview(big white view) respectively" this requirement can not be satisfied
2) Spacing on left and right can be decrease/increased by keeping overall requirements satisfied
I've struggled with this for years, so I finally decided to create a view to manage all these resizes like a HTML page: ETFlowView.

UICollectionView change flow direction on rotation

Hey, I'd like to obtain what you see in the pictures: in Compact Height mode (landscape iphone) both the red and the blue view have to take all screen vertically and half the screen horizontally. In Compact Width mode (portrait iphone)they have to take all the screen horizontally and half the screen vertically. Space between views should be same size in both modes.
I used to think I have to use size classes and auto-layout constraints, but everything I tried failed miserably.
Maybe I have to use a UICollectionView and change flow direction based on orientation (if that is even possible)?
A collection view is probably overkill, because you don't want scrolling and that's the whole point of a collection view--by the time you do the sizing to stop it you'll have done all the work necessary to set a non-scrolling layout.
This is possible with Size Classes in IB. First, In general you will probably find it helpful to name the views in the Document Outline on the left in IB. You will also want to use this outline rather than try to grab the tiny constraint H-lines.
Set up all the constraints except 1) constraints linking the
OrangeView and BlueView to each other, 2) the constraints linking
the OrangeView to the top and left(leading), and 3) The constraints
linking the BlueView to the bottom and right (trailing).
Change the size class setting at the bottom to w-Compact and
h-Any in the funky box system. Now we're designing for a compact width, so views on top of each other.
Create a constraints for vertical space for BlueView.bottom to
OrangeView.Top. Also create constraint for OrangeView to
superview.leading (or ledaing,margin) and BlueView to
superview.trailing.margin. If you select any one of these constraints and look at the Size Inspector on the right (the ruler) you should see an "installed" checkbox not selected, and below that a w-Compact h-Any and another installed box, this one selected.
Now, while keeping the constraint selected just to see what happens, change the sizeClass selector at the bottom to w-Regular h-Any. Notice that in the Document Outline to the left, it should get grayed out.
Now we are designing for regular, so side-to-side. Add constraints linking the views for horizontal space, BlueView.trailing to OrangeView.leading. Also link OrangeView.top to the superview.top or top aligned to BlueView.top, and same for bottoms. You can manually edit the frame first; if not, IB will automatically fill in the wrong values, so edit these after you create them, and verify they are w-Regular and h-Any. With the ViewController selected, select "update frames" and the views should snap to their expected shape for the size class.
Let us know if this works for you or if it was unclear. Good luck!

Resources