Search code examples
autolayoutxcode5

Why do I need 6 constraints when placing a view inside a UIScrollView?


Whenever I add a subview to a UIScrollView, I must add 6 constraints instead of 4.

How to reproduce the problem:

  1. Create a new Single View application.
  2. In the storyboard, add a UIScrollView which fills up the entire screen.
  3. Add its missing constraints (this should add 4 constraints to the superview, such as "Top Space to: Superview).
  4. Add a new UIView as a subview of the UIScrollView. Size it so it is a small rectangle.
  5. Choose to add the missing constraints on this box.

You will notice that it added 6 constraints:

  • 4 for trailing/leading/top/bottom to superview
  • 1 for width
  • 1 for height

If you try to delete the width or height constraints, all the constraints become orange. The view should be able to determine its width via its trailing and leading constraints. Similarly, the view should be able to determine its height via its top and bottom constraints.

Why are all 6 of these required, then?

Note: If you try this same thing with a UIView instead of a UIScrollView, then everything works as expected.


Solution

  • This is because a UIScrollView has a content size which must also be determined by the constraints. If you don't include the last 2 constraints, the content size does not know how big it should be.

    In reality, you actually need 8 constraints for a UIScrollView:

    Assume you have a single scroll view with a single button in it (or any other view which has an intrinsic size).

    You will need the following constraints:

    • 4 for positioning the scroll view's frame.
    • 4 for determining the content size of the scroll view.

    An example of the first four is:

    H:|[scrollView]|
    V:|[scrollView]|
    

    (This simply sets the scroll view's frame so that it takes up the entire screen.)

    An example of the last four is:

    H:|-10-[button]-10-|
    V:|-10-[button]-10-|
    

    (Note that each one of these lines creates exactly 2 constraints.)

    Assume the buttons intrinsic size is 50. With these constraints, we just set the content size of the scroll view to 70x70.

    More information can be found here.

    Apple also released some information regarding the behavior of scroll views and auto layout in the iOS SDK Release Notes for iOS 6. In there, they describe how to get it working with a "Pure Auto Layout approach" and a "Mixed approach."