Autolayout with specific constraints - ios

I have problem or maybe wrong understanding of constraints in general with view controller form photo below.
I already implemented scroll view and it is working properly. Photo below showing Content View with two subviews (with the same name: View). What I would like to achieve is to set first View (the blue one) to be exactly on edges of the screen and second one (green view) to be visible only when user scroll down on this page. Is it possible to achieve these just using autolayuots or I need to do some hard code work. What is the best approaches for solving this taking in account that I need this app to work with all king of iPhones.
At the bottom of the green view is located tab bar but it is not visible on this photo.

This is pretty straight-forward...
Pin your scroll view to Zero on all four sides.
set Blue Top, Leading and Trailing all to Zero to superview (the scroll view)
set Blue width equal to scroll view width
set Blue height equal to scroll view height
set Green width and height each equal to Blue width and height
set Green "center horizontally" to Blue
set Green Top to Zero from Blue bottom (vertical spacing)
set Green Bottom to Zero to superview (the scroll view)
That should do it :)
Edit: whoops, corrected step 4 (Blue height should be equal to scroll view height, not multiplied by 0.5)

Related

Setting the content size of a view inside UIScrollView

I have to lay out a few views in a View Controller which should look like this when run.
Initially the white view should be partially covering the blue view at the bottom like shown in the image. The blue view should stay put while the white view at the bottom can be scrolled over the blue view.
I added the blue view to the main UIView of the view controller. Then added a UIScrollView on top of blue view and added the white view on to the scroll view.
Now I'm getting the dreaded ambigeous content size error. I have pinned the scrollview on all four sides. Then added leading, bottom and trailing constraints to the white view. Then I tried adding a top constraint to the white view but the error still persisted. I also adding a height constraint to the white view to no avail.
It might be dofficult to imagine my setup so I added a demo project here as well.
I set the constraints for you here.
Explanation:
You are getting ambigous content size because your scrollView does not know its content (white view's) width and height.
I added top,width and height constraint to white view. This way your scrollView knows its content width and will scroll only vertically. As for content height - u can change heightContstrait's constant in code, or completely remove height constraint if you use autolayout properly for white view's subviews.
Put the blue view under scrollview. And set scrollviews content inset, to make your white view appear not on top, but with some space. Now on start you get white view a bit over blue, and on scroll it covers blue view. About size errors, scrollview needs to know it’s content size initially. I assume your white view is table view, so set it’s bottom constraint to zero. If you want blue size to change it’s size on scrolling, like it’s avatar or something, it’s a bit different. You should take scrolling events on uiscrolldelegate, and change blue views height accordingly
Make sure you've read (and understand) Apple TN2154: "UIScrollView And Autolayout", which explains the steps required.
Looks like you're not specifying the content size properly.

How to make grow UIViews proportionally

I have view simmilar to this below:
Views stack
How can I make it possible to make height of first and last view bigger proportionally, when making yellow view height smaller? Can I do it by setting content hugging priority and content compression?
Now that I apparently understand your problem, I suggest the following:
The top of the violet view has to be set equal to the top of the superview.
The height of the violet view is still undefined.
The bottom of you violet view has to be set equal to the top of the label.
The label has a fixed height.
The bottom of the label has to be equal to the top of the yellow view.
The yellow view has initially a fixed height.
The bottom of the yellow view has to be set equal to the top of the button.
The height of the button is still undefined.
The bottom of the button has to be set equal to the bottom of the superview.
This leaves the heights of the violet view and the button undefined. But your requirement is that their heights are proportional.
This can be achieved be setting them first to be equal to each other. Then double click the constrains and change the multipliers, e.g. make the multiplier of the violet view larger, and the multiplier of the button smaller.
Then you have an unbroken chain of vertical constraints, and auto layout should work correctly if you assign a height of 0 to your yellow view.

Constraints not resizing properly for all screen devices

I am trying to do the constraints for these horizontals button. I want the ratio of size of buttons to be the same, and the icons to be of equal widths and heights of each others.
Any idea of how i can do that so these buttons resize properly according to the screen size? Thanks!
Make groups of UIView containing the icon and text. Lets call this container view
Place all the n container views inside your storyboard as you would like them to appear. Now:
To the left most container view add a leading and bottom constraint to the super view.
Now to the second container view add a leading space of 0 (or anything you want). Control + drag your second button to the first button. Hold down shift and select equal width, equal height and align bottom.
Now apply the same constraints as your second container view to all your n - 1 container view. n being the number of container view you want to add. Now to your last (nth) container view add, one extra constraint, which would be a trailing space to the superView. Now all your container view ought to have an equal width that will be determined depending on the width of the screen!
If you want to have a specific height or aspect ratio to all your container view. Just add the height or aspect ratio constraint to your first container view and all your subsequent views will get updated accordingly.
OR
If you wish for the height to be dependent on the screen size and not maintain a specific aspect ratio, then you will have to give the first container view a equal height to the whole view with a specific multiplier like 0.15.
You will also have to add appropriate constraints to the icon and label present inside each UIView
Edit: A much easier thing for you to do would be add the icon as an image to the UIButton and add the text as you would normally to the UIButton. The UIButton will appear quite similar to the screenshot you posted. And then just apply the constraints I mentioned above.
Set the width and height as ratio of the SuperView. Set if for one button and for the remaining buttons make the height and width equal to the first button for which you defined the height and width in terms of superview height and size. Use this SO Post to see how to set height and width as ratio of the superview.
Hope this helps.
It's Simple because your All buttons are in single Direction so you can use StackView.
Just simple first apply the equal hight and equal width to all your buttons
now select all the buttons and add them in the stackview
it will be in the right side bottom. (with the constraint icon)
now simple Apply add missing constraint. it will done the work by own and gives better result. (but take care here apply it from the all views in View Controller Section)
And now Bingo try this every Size will show same.
This will work same in simulator also.
The solution is very simple.
See the image below (5 buttons)
The first (blue) button is pinned to the left and bottom of the superview
Each of the other 4 buttons (red, black, green, pink) are top aligned to the first (blue) button
Each button is using a horizontal spacing to the previous button (with a constant of 0). So red button has 0 horizontal spacing to blue, black has 0 horizontal spacing to red, etc
The Last (pink) button is also pinned to the right of the superview
Finally all 4 other buttons are set to have same width to the first (blue) button
That's it!
As for you icons, all you need is to set them to have same width & height to the first icon you have

View inside UIStackView is not resizing with AutoLayout

I have this following screen:
All of the views are inside an UIStackView. The yellow view would be circular on runtime. My issue when I run an a smaller iPhone (5S), the light blue view which contains the yellow view, will not get smaller, so the red and blue view from the bottom will shrink. I want these two and the green view to have fixed width and the light blue view to adapt height.
But for some reason it doesn't. I am sure is because of the constraints I set to the yellow view. But I can't figure out which one is the problem.
Here are the yellow view constraints:
The constraints for the other views are:
Green view: height = 64
Red and blue view: height = 50
Much appreciate if someone could take some time to look over this constraints and help me understand how to make the light blue (and yellow) to change height when screen changes.
Did you try lowering the Content Compression Resistance Priority (vertical) for the light blue and yellow views to be less than 750, and the Content Compression Resistance Priority (vertical) for the green, red and blue views to be higher than 750 (maybe even 1000 / required if that's the case?)
UPDATE
I took a look at your project. Actually, the issue doesn't seem to be with your stack views, constraints, or the DailyStatusViewController at all. Instead, the issue looks more related to the MainViewController which is embedding the Daily Status view inside a scroll view. The scroll view is both clipping to bounds, and is placed behind another container view. If you turn off clip to bounds on the scroll view, and move the container view below it to be behind it, you will see your stack views laid out correctly, but were just being clipped.
As to why they were clipped, keep in mind that your out stack view has a required height constraint of 300, while the scroll view it's being embedded in has a height constraint to 45% of the screen height. So on smaller screens, there is less than 300 points available to display the Daily Status view, and so it is being clipped. You probably want to remove the fixed height constraint from your outer stack view and instead constrain it to the edges of the root view.

Using AutoLayout and ensuring bounds of parent view to fit subviews when resized

I really wish I could get my head around auto layout. It seems that whenever I read an abstract description of how things are supposed to work it makes sense, but whenever I actually try and put it into practise it always causes massive headaches. So, apologies if there is already an answer out there for this but I couldn't find one.
The problem should be relatively simple. I have a container view, which contains two subviews, shown here in hideous colours for maximum readability :) :
The bottom (black) view, should remain at it's current size and maintain the spacing between it and the red view, and the spacing between itself and the bottom of yellow view.
The red view I want to be able to dynamically change its height, causing the black view to shift up/down accordingly whilst the yellow view resizes to fit both the red+black views.
For the black view, I've added constraints to:
Set the height to 94
Pin the leading and trailing space to superview
Set the top space to the red view at 51.
Set the bottom space to the yellow view at 20.
I am trying to understand what seemingly-mystical set of constraints I need to add in order that, when the red view is resized vertically, the black view stays its current distance from the red view and maintains its size, and the outer container view resizes accordingly so that it contains the red view + black view + vertical spacing between the views.
For the red view, I've added constraints to pin the top, left and right spacing to superview, but have had no luck working out the vertical constraints. Currently I've got a constraint pinning the height =114 with a priority of 999 and a constraint with height >=114 with a priority of 1000 thinking this would ensure the view is always at least 114 in height...
The fun starts when I try and manually set the height of the red view.... I've added a button on the view, and when the button is pressed, I manually set the bounds of the red view. (The red view's default height is 114):
CGRect bounds = self.redView.bounds;
bounds.size.height = 300;
self.redView.bounds = bounds;
When I run this and press the button, the view goes from this:
To this:
To me this makes no sense whatsoever. Why does this result in:
The Y origin of the red view changing? Particularly when there is a "required" constraint telling it to stay 20pts from the top of yellow view.
The spacing between the red and black views breaking down, even though the constraint on the spacing between them is "required"?
The vertical size of yellow view not changing. Again, despite the spacing between red+black, and me having tried just about every combination I can think of in terms of compression resistance and content hugging priority.....
I really want to understand this, so would be really grateful if someone can explain what additional constraints / changes to constants are required, but more importantly WHY they are required, because to me it doesn't seem clear at all how the layout system comes up with its answers....
Any clarification much appreciated.
Thanks in advance
(All code above is running on iOS 7 and built with Xcode 5.0.2).
You don't need any fancy constraints to do what you want here -- no inequalities or messing with the priorities. In addition to the constraints to the sides, the red view should have 20 to top, 51 to black view, and a height constraint of 114. The black view, has a 20 to the bottom and a height of 94. The superview (yellow) should have zero constraints to top, left and right -- no height. You should have an IBOutlet to the red view's height constraint. When you want to change its height, modify its constraint (don't set frames):
- (IBAction)resizeYellowView:(id)sender {
self.heightCon.constant = 300;
}
Everything is linked together from the top of the yellow view to the bottom with fixed values, so the only thing that can change when the height of the red view changes, is the height of the yellow view.

Resources