For any view, the frame and its content's sizes are the same ie if you have some content (e.g. image) with the size of 200 * 800 then its frame is also 200 * 800.
This is NOT true for scrollview's contents. The content is usually bigger than the frame size of the scrollView. If content is same in width, then you only scroll vertically. If it's same height then you only scroll horizontally. Hence it's the only view that needs 6 constraints not 4. For any other view having more than 4 required constraints will cause a conflict.
To setup your scroll view, its contents and position of scrolling, you basically need to answer three questions:
- How big is my frame? ie at any given moment how big should the scrollview be? e.g. I only want to use half of the screen's height so
scrollview.frame = (x: 0, y:0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height / 2)
How much scrolling space do I need? ie How big is the content? e.g. the frame can be just 500 points of width, but then you can set an image with 7000 points, which would take quite some time to scroll horizontally. Or let it be exactly 500 points of width which then means no horizontal scrolling can happen.
How much have you scrolled at the moment? Say your content's (or image) width was 7000 and the frame size is just 500. To get to the end of the image, you'd need to scroll 6500 points to the right. The 3rd part really doesn't affect the constraints. You can ignore that for now. Understanding it just helps how a scrollView works.
Solution
Basically if you leave out the 2 extra constraints (about the content size) then the layout engine will complain due to the ambiguity. It won't know what area of the content is hidden (not visible in the scrollView) and what area of the content is not (visible in scrollView) hidden.
So make sure you add size constraints for the content as well. For more on that see this answer
But some times I don't add size constraints to my views and it just works. Why is that?
If all the contents you've added into the scrollview are constrained to the edges of the scrollview, then as the content grow the scrollview will add space to accommodate. It's just that you might be using UIView
s where its intrinsicContentSize
is 0
so the scrollView will still complain about ambiguity of its content. However if you've used a UILabel
and it has a non-empty text, then its intrinsicContentSize
is set (based on Font size and text length and line breaks, etc) so the scrollView won't complain about its ambiguity.