Search code examples
iosobjective-cuiscrollviewautolayout

UIScrollView - Need Constraints for x position/width, Need Constraints for y position/height


I have a view hierarchy that looks like this (based on other answers and Apple's advanced AutoLayout guide for working with UIScrollView):

enter image description here

The 2 steps required for ScrollView are:

  1. Set up constraints for position and size (frame) of ScrollView: The same way you do it with any other view.
  2. Set up constraints for content size: By making sure that there are constraints from the ScrollView's subviews touching all edges (leading, trailing, top, bottom) of the ScrollView, if you're doing this in interface builder and not programmatically.

Step 1 worked fine at first and this was the result:

enter image description here

enter image description here

No problems with position and size as expected. I just need to define the content size (content height and content width) now in Interface Builder with Step 2.

Now I add the constraints touching all 4 edges of the ScrollView like so:

enter image description here

Suddenly, the ScrollView doesn't know it's position and size (frame) anymore.

enter image description here

I've looked at other answers and followed the various steps, but can't seem to resolve this issue. Sorry I'm not able to post Storyboard screenshots because of privacy issues


Solution

  • Scroll views can be a little tricky at first. You really have 3 parts:

    1. Actual frame of the scroll view
    2. Actual frame of the subview(s) contained in the scroll view
    3. The contentSize of the scroll view - that is, how far it should scroll in either direction

    So, 1. is pretty straight-forward.

    The second part also seems straight-forward, except that we tend to "pin" subviews to the inside edges of their superviews. In the case of scroll view subviews, those constraints are what defines the contentSize. You also have to make sure the subviews have a "size".

    Starting with just one subview, you would:

    1. set the scroll view's constraints as "normal".
    2. set the size of the subview - just for demo purposes, set it to 100 x 100
    3. pin all four edges of the subview to the four edges of the scroll view

    Run the app. Assuming you set background colors so you know what you're looking at, you should see the scroll view positioned and sized as you'd expect... you should see the subview of 100 x 100 sitting somewhere inside the scroll view... and you will likely not be able to do any actual scrolling.

    If you go back and change the subview to, say, 100 x 800, and still have its bottom constraint pinned to the bottom of the scroll view (the subview's superview), and run the app again... You should be able to scroll up and down for the full 800 pt height of the subview.

    The way to think about it is: the scroll view's content - whether it's one or many subviews - has to define its own size, which will define the scrollable area (the scroll view's contentSize).

    Hope that makes sense!