Autolayout: Adjust view height based on newly set constraints - ios

I just started using AutoLayout more thoroughly, and I encountered a big problem:
I have a view with some subviews attached to its top and some subviews attached to its bottom, so when the view is changed in height the subviews are moved accordingly. Depending on user actions the height of the subviews can change (= their height constraint values change), and this can lead to a situation where they don't fit in their parent view anymore.
How can I find out whether a new set of constraints will make it necessary to change the parent view's height in order to accommodate all of its subviews? Preferably before I display all fields with the new constraints - I'd like the view's height to change at the same time. Reason for this: I animate the change of constraint values, and I'd like to animate the view height change at the same time. Already performing the new constraints by calling layoutIfNeeded is out of the question because of this.

The question is not clear enough, but couldn't you just get the height of each subview and compare the summary value with parent view's height?

Related

Resize view in UIScrollView

I am so confused about UIScrollView.
I'm working with a view contains many other views. And that view placed in a UIScrollView.
How can I change height of this view?
I've tried so many ways but they didn't work. I tried to change frame by CGRect but view's child went wrong.
First of all you should be using constraints using auto layout.If all the constraints are justified then the there will be no warning.At that moment the scrollview will fit all the views under its contents view and mange the content size of it by itself.
If you want to increase any view in the scrollview to increase in height you may increase the height constraint and the scrollview will manage the constentsize by itself.

AutoLayout: how to constrain UIView to be no taller than the height needed to contain all its subviews?

There are a few answers on SO that seem to address the same question, such as this one. However, none of these worked.
The goal is to use AutoLayout and Storyboard to create a UIView, call it parentView, that is tall enough to contain its subviews and no taller.
This can easily be done in code, but the goal is to do it all within Storyboard with AutoLayout constraints and without having to specify a static height (e.g., assume one of the subviews is a UILabel so parentView would need to grow correspondingly if the UILabel's height grows because of long text).
Is this possible?
This can actually be accomplished not with the addition of constraints, but the lack thereof!
Drag a new View into the superview and give it two constraints: Center X and Center Y. Drag some views/labels and add them to the View.
In order for this to work, the subviews inside must have constraints to the leading/trailing/top/bottom of the View holding everything together. This "defines" constraints for the View's width and height so XCode doesn't get mad at you.
That's it. Example project.
Edit: Image of the view and constraints

Remove one view's layout constraints but keep its subviews'?

Working on a project in iOS 8 using storyboard and auto layout:
In storyboard, specified constraints for this view and its subviews
In code, in response to touch events, I'm going to change this view's size by setting its frame
To make both 1 and 2 warning free, I'm doing the following when first changing its size with code:
[theView removeConstraints:theView.constraints];
theView.translatesAutoresizingMaskIntoConstraints = YES;
theView.frame = CGRectMake(0,0,width,height);
If not doing the first line, Xcode will complain a whole bunch about constraint conflicts, however adding this line will remove all its subview's constraints as well. So my question is: is there way to just remove this uiview's constraints but not its subview, say a button on it still wants to center its self relative to this view's size and position?
First, you don't need to resize the view by setting frame otherwise what is the point of keeping the constraint at first place. You could have position that by simply having a correct initial frame.
Secondly, you have a mis-conception about "TO-WHOM" a constraint has been applied to.
say a button on it still wants to center its self relative to this view's size and position?
When you apply a position related constraint to a view you normally apply it to it's superview. Means if you want to position a subview in the horizontal centre of a view then the constraint is added on view not on the subview. That's why when you called a removeContraints: message on view that position constraint was removed and now your subview isn't bound to any constraint. However the width and height constraints are applied to subviews itself.
To solve this you need to make IBOutlets for constraint that you need to modify, which in your case should be width, height, horizontal x and top constraint; and then change the constant values for them respectively.
theView.widthConstraint.constant = newValue;

How to change uiview's height using auto layout?

So I created this scenario in order to understand how views increase in height according to their content. However am still not able to make it happen.
This is what I have now:
the textview is growing according to content. however the uiview containing it is disappearing. what constraints should I use so that when the uitextview becomes bigger, its parent view also increase in height?
Start by clearing all your constraints from everything so we have a fresh slate.
Step 1: Build your view hierarchy. In this example, we want something like this:
The view controller's view, which we'll call parentView has a subview, which we'll call redView. That redView has a child, a Text Field, which we'll call textField.
The hierarchy looks like this:
Step 2: Set any constraints that are specific to any individual view. In this case, we probably only want to set a width constraint on our text view. For now, I'll just set a width of 200pts.
Step 3: Set the constraints between textView and its parent, redView. Let's say we want a 10pt border all the way around. Let's add these constraints:
Once we've added these constraints we'll gets some auto layout warnings and errors. For starters, because the constraints I added for with and space to superview don't match the actual sizes, I'll get some warnings like this:
There will also be some errors describing missing X and Y positions for redView and for textView. There are really twice as many errors here as necessary. textView knows where to position itself relative to redView. We don't need more constraints to sort out textView's position. However, redView doesn't know where to position itself yet... and so ultimately, textView also sort of doesn't exactly know.
We can update the textView's frame to get rid of the warnings, but let's go ahead and fix the actual errors.
Step 5: Set up redView's constraints relative to the superView. redView already know what size to be. Notice we had no errors for redView's width. It just doesn't know where to be. In this case, I'll go simple and say we want redView to be centered. So we'll want to add these constraints:
Now we've fixed some of the problems. The only problem that remains is the height for everything.
To fix this, we must set the content sizing priorities of textView. Set these all to 1000 and change the "Intrinsic Size" property to "Placeholder".
By now, all of the auto layout errors should be gone and we should only be left with warnings because our storyboard frames don't match what our constraints say they should.
We can fix that by selecting parentView and updating all the frames:
There's one final caveat to this auto layout puzzle when it comes to autosizing based on content size: what happens if our text view has no content?
If our textview has no content, auto layout will choose a height of 0, and our users won't even be able to see that there's a text view there, much less tap in it to add content (and make it expand). When using auto layout and content-based sizing, we should almost always be sure that we've set either an explicit or minimum size for the content view.
We don't have to worry about our textView's width, as we set this explicitly to 200. So let's add a minimum height constraint. Start by adding any height constraint:
Now go to the size inspector for the textView, find this height constraint we added, and edit it into a greater than or equal to constraint:
Storyboard won't reflect the change in content in our textView and resize it appropriately, but your constraints are now set up correctly and this will behave appropriately on your device or in the simulator.
ON UITextView make your you unselected These
Scrolling Enabled
Bounces
Bounce Horizontally
Bounce Vertically
Shows Horizontal Indicator
Shows vertical indicator
Now Change your auto layout constraints like this.
On the Storyboard Page, click on your textview.
Then click on the small triangular in the lower right corner.
Click first on "Clear Constraints".
An then on "Add Missing Constraints".
Its the easiest way.

Pure autolayout with a UIScrollView

I'm trying to get a UIScrollView working with autolayout positioning and sizing. I'm following the guidelines for a "Pure Auto Layout Approach" in this documentation, but I'm having a hard time getting it to work.
My hierarchy looks like this:
UICollectionViewCell -> UIView -> UIScrollView -> UIView.
Everything is positioned with autolayout constraints, including the UIScrollView (which is positioned relative to it's direct parent UIView). The UICollectionViewCell does have a fixed size eventually, as it's set by collectionView:layout:sizeForItemAtIndexPath, but I don't think that's relevant this this issue.
The issue I'm having is that the content of the last UIView (the child of the UIScrollView) isn't showing up. If I manually give it a frame size, it does show, but I really want to use autolayout.
There's a line in that documentation article that I don't quite understand:
Position and size your scroll view with constraints external to the scroll view.
Does this indicate that I can use autolayout to position and size the scroll view within it's parent, or does the scrollview have to have a fixed frame?
Autolayout with UIScrollView may seem too complicated at first. Conisder following two things:
1) UIScrollView externally behaves like any another UIView. This means, you can set any position/size to it with auto layout constraints. No differences from UIView.
2) UIScrollView internally CAN (but not should) calculate it's content size basing on given auto layout constraints inside it. For this behavior you should give one odd explicit horizontal & vertical constraint for it.
Say: you has UIView child inside UIView parent. You pin left, top, bottom, right from child to parent. There are ENOUGH constraints, to calculate child's position and size - it's ok.
Now, you do have UIView child inside your UIScollView parent - and the same set of constraints. There are NOT ENOUGH constraints to calculate scroll view's content size. For calculating scroll view's content size, you should set for example equal widths & equal heights constraints for your child to your UIScrollView parent.
Despite you've given not enough info to find your problem out, i think, you most likely didn't set constraints to size/position your UIScrollView inside it's parent. After that - you probably didn't set one more explicit constraint in each direction inside the scroll view to calculate its content size.
I strongly suggest to read ray wenderlich's iOS 6 by tutorials autoalayout parts - you will understand HOW and WHY auto layout works so.
Say you are working with a nib whose size is 568 in height, and the inner view is 650 high.
First make the scroll view the same height as the inner view. Then pin the four sides of the scroll view to its container view, however you will notice that the bottom constraint is a negative number - make this 0.
You will notice that there is a problem with the bottom constraint:
Don't worry, that will be fixed in the next step.
Now pin all four sides of the inner view to that of the scroll view, as well as its width and height:
You will now notice that the previous error has disappeared, and when you run the project, you should now be able to scroll to see the content out of view.

Resources