NSLayoutConstraint equal height does not divide equally - ios

In my app, i need to put some boxes and make sure first two of them divided equally.
Navigation bar + status bar holds 64 point.
Fixed height constraint of 60 point set to welcome box.
Fixed height constraint of 145 point set to brown box.
Tabbar holds 50 point.
Rest of the height which is 417 point should be divided into two.
Green and Red boxes has its scrollviews in themselves. Scrollviews has layout constraint of same height, top, bottom, leading and trailing constraint for that of its superview.
After layout is done, i inspected that red box has height of 208.66667 and green box has 208.3333.
But each scroll views have height of 208.6667. So the scroll view at green box becomes vertically scrollable because its height(contentSize height) is bigger than that of its superview.

You have some options.
Resize the content of the scroll views to be 208px and ignore the left-over partial pixel.
Disable scroll bars on the scroll views if you don't need them.
Add a pixel to one of the other areas so that the red and green views can be equal heights.
Size the views to the exact pixel dimension you want rather than just an "equal height" constraint.

Related

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.

Need help to set autolayout

Am new to iOS & am facing it very difficult to set autolayout. Watched many videos to learn, but all of them giving solution to a specific problem. No video covers all base rules to set an UI object into it's place & with proper flow.
I came from Corona Background & used to set UI programatically very well. Am thinking here same way, but I think apple made it so difficult or people are not able to explain me properly.
Please see 2 images attached in this question & tell me rules to apply to achieve this UI. I request you people to please explain in the general manner so that my other screen can be completed using same rules.
Image 1: http://i.stack.imgur.com/MPE47.png
Image 2: http://i.stack.imgur.com/qEiCm.jpg
A really helpful guideline is
Every element should be able to figure out its position (x and y) and size (width and height).
Ensure that every element only has one way to figure out its position and size.
Remember that the autolayout of all the elements can influence each other.
The most used layout constraints are:
Top The space between the top of the view to another view.
Trailing The space between the right edge of the view to another view.
Leading The space between the left edge of the view to another
Bottom The space between the bottom edge of the view and another view
Width Assign a fix width to a view (Note that it can also be a percentage - aspect ratio)
Height Assign a fix width to a view (Can also be a percentage)
Center Horizontally Always align the view relative to the horizontal center of another view
Center Vertically Always align the view relative the the vertical center of another view
For example in your second image, say the yellow bar is a UIView called titleView.
Set the position of titleView by setting the top layout constraint to the container view. y position is set.
Set the leading constraint to the container view. x position is set.
Set the trailing constraint to the container view. The view's width will now stretch with the screen size. Thus width can now be determined.
Set height to 50. Height is set.
Now... If you also set the width of this view, it will cause the layoutConstraints to break, because you have redefined the width constraint. Some of the constraints will then be ignored.
Another example of how layoutConstraints might influence each other. Lets look at determining the y positions of the second image.
Say titleView has a top constraint to the container + height of 50.
currentCampaignView has a top constraint to the bottom of titleView. (Use vertical spacing) + equal height to titleView. (y + height can be calculated)
the 5 buttons have equal heights. Top buttons have Top space to Bottom of currentCampaignView. Centre buttons have Top space to bottom of top buttons. Bottom button have Top space to bottom of centre buttons.
startCampaignView has equal height to currentCampaignView. Top constraint to bottom of bottom button and Bottom constraint to container view.
Note that because views and buttons have equal heights, all are considered when determining the height. Thus it is very important that they are all interlinked and that the entire height that can be used is specified. In this case it is specified by the first element titleView that has a Top Constraint to the Container view (of which the height should be known) and the last element, startCampaignView, that has a Bottom constraint to the Container view. Because all the views in between are linked on y position and height, the view can work out what each view's height and y position should be.
One more example. (Your first image)
topLeftButton Set the top constraint to Superview. (y), Set the leading constraint to Superview (x), Set height = 100 (height), Set equal width to topRightButton (Note that we do not quite have the width yet, because the width of topRightButton can not be determined)
topRightButton Set the top constraint to Superview. (y), leading constraint to topLeftButton (will be used for x), Set trailing constraint to superview. Now the width of both buttons can be determined, because we have an external startX + endX and we know the two buttons touches each other and are equal widths. Thus the available space will be split to get the width of the two buttons.

Three proportional views autolayout

I have three views I want to divide in a superview.
Currently, when I set proportional heights, I get weird results when updating the multiplier in those constraints.
As you can see, there is weird space between the top and the first proportional view and the second.
I want no room in between.
Who can help me out?
Two things immediately
It would be simpler to set the proportional height in this case between each of the views and their superview. This may not be what you want but either way my example below would work with slight tweaking
You only need to set two of the views to have proportional height. The third view (the one in the middle) can just take up the remaining space in between them.
See the Red, Green and Blue views -
The red view hugs the top, left and right and has a proportional
height
The green view hugs the bottom, left and right and has a proportional
height
The blue view hugs the left and right and has vertical spacing (zero)
to the red view and vertical spacing (zero) to the green view.

Autolayout Issue with Multiple Button Aligned Horizontally & Vertically with a Label

Please look at the ScreenShot attached for wCompact|hRegular for different screens, I am trying to make it working since hours but not getting any success. My requirement is that at the top there would be a label with some predefined margin. Although the Label content would render at the runtime, but I know the content size, so resizable label isn't needed actually I think. Now there would be three row at equal distance. In first and third row, there would be two buttons with equal height and width and in second row there would be button aligned horizontally. I have set the buttons image and text in storyboard. Control Alignment are set to Horizontal | vertical. Constraints for label are:
Pinned top space to superview, leading and trailing space equals to:8(superview), height equals:90.
Constraints for Button(View Transactions) are:
top space to label, bottom space equals to:8(New Launches Button) leading and trailing space equals to:8(superview) and 8(Place Request Button) respectively, and equal width and height for all buttons.
Looks fine for 4.7 and 5.5 But not satisfied with the output for smaller screens. As u can see resizing of buttons image not working properly(Larger space between button's image and text). One more thing is I don't wanna set the height of the label, cause it seems like a wrong practice in AutoLayout. Any help would be much appreciated.
You should set the Aspect Ratio for the Buttons, not just the equal width and height. In that case auto layout wont shrink the images.
Really you should put this into a scroll view so that if the height is too great the user can still see everything by scrolling. You should also not set static heights on labels, you should allow the intrinsic content size to apply.
Add a subview to your new scroll view. Pin the width of this subview to the width of the scroll view. Do not pin the height.
Add all of your buttons and labels to this new subview. Pin them to the edges of the view and allow the intrinsic content sizes to apply limits. Set various items to have equal widths and heights. Do not set explicit heights or widths (do everything by proportion or equality so auto layout can choose good sizes).

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