UIScrollView doesn't use autolayout constraints

SirRupertIII picture SirRupertIII · Nov 21, 2012 · Viewed 84.6k times · Source

I have a scroll view and an image view behind it and I am populating it with nibs. I am using autolayout. I have a bottom space to superview and a top space to superview on both of the views. The image view does exactly what I want it to do. For iphone 5 it is where I want it. And for the other iphones, it stays above the bottom of the screen, so it resizes correctly. The scroll view looks right on the iphone 5, but on the other phones it doesn't get resized, so it scrolls down below the view of the app. I get these messages in the log:

 2012-11-21 10:42:38.576 LCHApp[12604:907] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
  Try this: (1) look at each constraint and try to figure out which you don't expect;
  (2) find the code that added the unwanted constraint or constraints and fix it.
 (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer
  to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 

"<NSLayoutConstraint:0x1d8ea080 UIScrollView:0x1d8413b0.bottom == UIImageView:0x1d892110.bottom>",
"<NSAutoresizingMaskLayoutConstraint:0x1d8cca10 h=-&- v=-&- ScheduleViewNib:0x1d853630.height == UIScrollView:0x1d8413b0.height - 386>",
"<NSLayoutConstraint:0x1d8e5340 V:[UIImageView:0x1d892110]-(64)-|   (Names: '|':ScheduleView:0x1d8efc30 )>",
"<NSAutoresizingMaskLayoutConstraint:0x1d8cf520 h=--& v=--& V:[ScheduleView:0x1d8efc30(480)]>",
"<NSLayoutConstraint:0x1d8eaed0 V:|-(45)-[UIScrollView:0x1d8413b0]   (Names: '|':ScheduleView:0x1d8efc30 )>"


 Will attempt to recover by breaking constraint 
 <NSLayoutConstraint:0x1d8ea080 UIScrollView:0x1d8413b0.bottom ==      UIImageView:0x1d892110.bottom>

I already tried

[self setTranslatesAutoresizingMaskIntoConstraints:YES];

and

[self.myScrollView setTranslatesAutoresizingMaskIntoConstraints:YES];

From what I can see this just takes off all constraints from the views. And isn't what I want.

Answer

matt picture matt · Nov 25, 2012

The relationship between UIScrollView and auto layout is different from other aspects of auto layout. Basically, if simple auto layout were allowed to operate, nothing would scroll. For example, if a subview of the scroll view were pinned in the normal way by a constraint to 10 points from the top of the scroll view, it would be absolutely pinned there; it would never move, no matter how the scroll view were scrolled.

To solve this problem, a UIScrollView that uses autolayout operates in a completely new way. Therefore when you say "I am using autolayout" you must prepare for things to operate very differently from before. You must either use a single scroll view subview with translatesAutoresizingMaskIntoConstraints = YES, and an explicit content size, or else everything must have translatesAutoresizingMaskIntoConstraints = NO and the content size will be deduced implicitly based on the constraints of the subviews.

This is very well explained in https://developer.apple.com/library/content/releasenotes/General/RN-iOSSDK-6_0/index.html