Search code examples
swiftimageautolayoutscrollviewzooming

Use a scrollview to zoom an image in Xcode 11 avoiding the "Ambiguous Content Size" AutoLayout error


My question is about the auto layout problem with scrollviews.

I'm just trying to add a scrollView on the storyboard, with its own constraints to the superView, but without any subviews inside it, and add an imageView inside it ONCE THE APP IS RUNNING. But with the "ambiguous content size" error on storyboard, autoLayout does not work on the scrollView, even if we uncheck the option "check of ambiguity". And IF I APPLY THE SOLUTION of adding a contentView to the scrollView, and pinning it with all those extra constraints, I ca still pinch and zoom the image inside the scrollView, but LOSE THE ABILITY TO PAN, whether the viewForZoom be the contentView or the added ImageView. If the ContentView is an imageView I have the same problem. Can zoom, can't pan.

Also, can anybody explain to me why this nonsensical "ambiguous scolding content error" is triggered in this Xcode version when the ScrollView has no content? Why do we need to pin a contentView with two redundant constraints, often to the scrollView's superview?


Solution

  • Interface Builder / Storyboard has no way of knowing that you will be adding subview(s) and constraints at run-time.

    So, it is telling you that your current layout has an Ambiguous Content Size.

    Would it be better to not show the message if the scroll view has no content? Maybe... but even though it is showing a design error, that doesn't mean you must fix it.

    If you really want to get rid of the warning/error, couple options:

    1) Add your imageView (with proper constraints) in Storyboard, and set the .image property at run-time.

    2) Add a subview (with proper constraints) in Storyboard, and remove that view in viewdidLoad() before adding the imageView.


    Edit

    Here's a simple example: https://github.com/DonMag/ZoomTest

    In IB / Storyboard, I added a UIScrollView and set only the width, height, centerX and centerY constraints, so Storyboard tells me Ambiguous Content Size.

    In viewDidLoad, I add a UIImageView, set proper constraints, set scroll view delegate and min/max zoom scale.


    Edit 2

    Results using a 256 x 256 image, and constraining the scroll view to fill the parent view (scroll view background is cyan)...

    On load - zoomScale == 1:

    enter image description here

    On load - zoomScale == 1 - rotated:

    enter image description here

    zoomScale = approximately 1.5 (just wide enough to fit):

    enter image description here

    zoomScale = approximately 1.5 - after rotation:

    enter image description here

    zoomScale == 5 - panned to top-left:

    enter image description here

    zoomScale == 5 - panned to top-left - after rotation:

    enter image description here

    zoomScale == 5 - panned to lower-right:

    enter image description here

    zoomScale == 5 - panned to lower-right - after rotation:

    enter image description here