25

I have:

  • application, that should work in landscape and portrait mode.
  • view with full-size scroll view on top.
  • some view inside scroll view with fixed width and height. (with added H and W constraints)
  • set to view inside scroll view as horizontal centered in container. (added according constraint)

I have warning in interface builder "Has ambiguous scrollable content width". enter image description here

The only way to fix this problem, that I know - is set trailing and leading constraints. But for different iPhones (5.5", 4.7", 4") I need to set different trailing and leading constraints.

How can I eliminate this warning and still have centered horizontally view with fixed W and H for all iPhone sizes?

I create Github repo to illustrate this problem: ScrollViewAmbigous

This is not duplicate of UIScrollView Scrollable Content Size Ambiguity , but it similar (and not answered although), but this question especially related to different sizes of iPhones.

Community
  • 1
  • 1
skywinder
  • 21,291
  • 15
  • 93
  • 123

3 Answers3

46

In the morning with a fresh cup of coffee I figured out workaround for this issue!

So, here is the initial state for simplest case:

  1. scrollView with 0 constraints to all edges
  2. Button centered Horizontal and Vertical with fixed Width and Height
  3. And, of course Has ambiguous scrollable content width and Has ambiguous scrollable content height annoying warnings.

1

All, that we have to do is:

  • Add 2 additional constraints, for example "0" for trailing and/or bottom space for our view (in my case - UIButton)

Important: you have to add trailing and/or bottom constraints. Not "leading and top" - it's not works!

2

You can check it in my example project, that demonstrating how to fix this issue: ScrollViewAmbigous

P.S.

I don't know why it works and how Xcode detect which constraint is more prioritised (because I'm not set priority for these constraints explicity), but I'll be thankful if someone explain, why it works in comments below.

skywinder
  • 21,291
  • 15
  • 93
  • 123
  • Thanks for your solution, I have very similar issue: how to make UIButton scrolls inside UIScrollView in your example? – Ponf Nov 16 '14 at 11:18
  • @Ponf If `button size` + `constraint` >= `size of the screen` - it will scroll. – skywinder Nov 17 '14 at 07:12
  • it was my mistake, I've forgot to set `alwaysBounceVertical` to `YES`. Thanks for explanation! – Ponf Nov 17 '14 at 08:03
  • 2
    Yees!! Spent half an hour on this thing! Before I added the bottom constraint, I was getting that message. Also when I was scrolling, it was always returning to the top of the scroll view. So after adding this constraint it finally scrolls normally plus the warning is gone! Thaaank you! @skywinder – manosim Jan 02 '15 at 22:31
  • 2
    Thank you so much for this solution. I found out that when there are more than one element (ex: 3 UIButtons aligned vertically one after another) the constraints must be added the bottom most one. https://github.com/skywinder/scrollViewAmbigous/pull/1 – coder9 Jan 24 '15 at 14:46
  • 2
    This does not appear to work when the ScrollView's subviews are meant to be the full height/width of the scrollview itself. Consider a scrollview that fits the viewport with several "cards" that are also the size of the view port. When the height/width is variably dependent on the view, you can't hard-code the height/width. – d2burke Mar 12 '15 at 13:41
  • @d2burke ok. Have you got solution for this case? If you know better solution - please [add another answer](http://stackoverflow.com/questions/26261659/uiscrollview-centered-view-ambigous-scrollable-content-size-many-iphone-si/26273632?noredirect=1#comment46267670_26273632)! – skywinder Mar 12 '15 at 13:50
  • I don't currently, and sadly. However, I noticed that you've pasted this same answer in several places and it doesn't work in the case that I described. It's a patch for a very specific case, not a complete solution. No big deal, but I thought I would contribute this comment. When I've solved it, I promise I'll come back and post an answer. – d2burke Mar 12 '15 at 13:52
  • @d2burke Yes, there is another answer [here](http://stackoverflow.com/questions/19036228/uiscrollview-scrollable-content-size-ambiguity-xcode-5-ios-7-interface-builder?lq=1). Agree with you. It's seems, that is a bug in Xcode, and it's just a dirty workaround. Hope they fix it in next releases. – skywinder Mar 12 '15 at 14:03
  • Yep, that's what I was referring to. Still, neither even approaches a solution to child views which are meant to fill the full width/height of the scroll view. If my case was time-sensitive, it could be quickly fixed by setting the scroll view content size in viewDidLayoutSubViews, but I'm searching for an Autolayout-only solution. – d2burke Mar 12 '15 at 14:08
  • Possible Principle... (1) The scrollview will scroll if it's content size > containing view. (2) The content size is set by an object on the scrollview in my case it's a text view. (3) you can constrain objects to anywhere on the scrollview. The 'No top and right' is Hocus Pocus – user462990 Feb 20 '16 at 12:20
8

Problem :

  1. The warning is telling us that the the content size of the scrollview depends on its subviews.
  2. while your subview don't have any strict rule of position and size (no fixed constraints) it will confuse nib generated scrollview content size.

Solution :

  1. Make only one subview as a 'contentView' for scrollview.

  2. Add strict (fixed) constraints to that 'contentView'.

    Best practice : equal width and height to its scroll view.

  3. Add all other subviews and constraints to your 'contentView'.

Community
  • 1
  • 1
Timur X.
  • 161
  • 1
  • 7
  • 7
    Equal Width and Height to the scroll view will render the content view, and hence, the scroll view, useless. – Darvish Kamalia Mar 13 '16 at 05:42
  • Run time you can change the bottom of contentView as the bottom of your bottomMost view in contentView. This way you can change the height of contentView. – Hitendra Solanki Apr 21 '16 at 21:39
  • Thanks for the solution. why does scroll view has to have a content view? Shouldn't it understand itself that whatever is added in the scroll view should be scrollable in the given order? – A_G Feb 01 '17 at 11:39
  • @AsthaGupta because UIScrollView is a subclass of UIView, and has extra properties, methods, delegates, etc. So its richer than UIView. While .contentView is a simple UIView. Basically better management with the .contentView inside a UIScrollview. – Timur X. Feb 02 '17 at 12:11
0

There seems to be a lot of confusion on this issue. My take is that a UIScrollView must have TWO trailing space constraints, an 'inner' one connecting it to one of it's subviews (so it can know its content width), and another 'outer' one connecting it to a sibling or superview so it knows its frame width.

Same principle applies for height, i.e. two bottom space constraints.

Reuben Scratton
  • 38,595
  • 9
  • 77
  • 86