UIScrollView doesn't use autolayout constraints

Objective CUiscrollviewConstraintsAutolayout

Objective C Problem Overview


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.

Objective C Solutions


Solution 1 - Objective C

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

Solution 2 - Objective C

Very important when using auto-layout: you must pin the right and/or bottom of the last subview to the right and/or bottom of the scroll view. This is how the scroll view knows the content size. For example:

[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:lastSubView
                                                 attribute:NSLayoutAttributeRight
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:scrollView
                                                 attribute:NSLayoutAttributeRight
                                                multiplier:1.0
                                                  constant:0]];

My thanks to this site for providing the perfect example.

I lost hours because of this, and I hope to spare others my pain.

Solution 3 - Objective C

To get UIScrollviews to work nicely with constraints, I use this approach answered here. In that answer, I tackle how to get a vertically scrolling scrollview working that also works with device rotation. You can tweak the approach to work with horizontally scrolling scrollviews too. For scrollviews that scroll in both directions, don't add the size matching width constraint trick. But do everything else the same.

Solution 4 - Objective C

A couple of things.

  1. make sure autolayout is on (IB on the "File Inspector Tab")
  2. Make sure you are NOT making any changes that involve bounds, frame, etc. - this is all done by Auto constraints now
  3. Make sure you stay away from AutoResizingMask. This will compete with your new settings. If these are done right, you can now layout your button and it will work great. Here's how.

This error is stating that either your nib or an a control within that nib is NOT using auto layout.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSirRupertIIIView Question on Stackoverflow
Solution 1 - Objective CmattView Answer on Stackoverflow
Solution 2 - Objective CphatmannView Answer on Stackoverflow
Solution 3 - Objective Cn8trView Answer on Stackoverflow
Solution 4 - Objective CJustLearningAgainView Answer on Stackoverflow