By SirRupertIII


2012-11-21 18:11:14 8 Comments

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.

4 comments

@matt 2012-11-25 03:37:05

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

@jrturton 2013-01-20 20:49:32

You may be interested in this question: stackoverflow.com/questions/14307037/… (not least because of the bounty!) I think this is a scrollview / autolayout issue but to my mind it reads like a bug - in this case the scroll view is a table view, and the content size is not adjusting properly on rotation.

@edelaney05 2013-04-13 20:12:03

@matt I don't know if you've seen this behavior, but if you use only layout constraints to define a scroll view's content size, there is a bug: scroll the content offset away from (0, 0) move to another tab or modal view controller, come back and the subviews of the scroll view are all shifted by the content offset and you can't get back. I would be grateful if you could confirm this and dupe my radar: openradar.appspot.com/radar?id=2932404

@matt 2013-04-14 00:37:03

@edelaney05 I think I can confirm the bug, but before submitting to Apple you should make a demo project, esp. since copy-and-paste code in openradar.appspot.com/radar?id=2932404 won't even compile (you've typed the name of constraintsWithVisualFormat:options:metrics:views: wrong). Always use real code that actually works. And besides, in a real project you can include an actual image. The Apple people have no imagination and no time; you must do all the work for them in advance.

@edelaney05 2013-04-14 01:55:25

Here's the sample project I sent w/ the bug report. :-) db.tt/yKK90TFk

@matt 2013-04-14 02:18:25

@edelaney05 "shoulder consectetur pancetta"???? :) OK, good. I actually did one much more closely based on their code, with an image view sized to a big picture. By giving the scroll view a red background color, and with logging, it was very clear that the scroll view thought everything was right (content size, content offset), but was drawing the image view in the wrong place, i.e. offset by the amount of the content offset from when we left the view.

@edelaney05 2013-04-14 20:12:41

@matt baconipsum.com ! :-) Awesome. Exact same behavior I was seeing. Scroll view reported everything as "normal," but drawing was incorrect by a factor of the offset. Thank you for confirming that I'm not crazy (but, only with regard to this bug!).

@matt 2013-04-14 21:13:16

@edelaney05 And of course this is just the kind of bug I want to know about, so thanks for telling me. (Also thanks for the baconipsum ref!)

@phatmann 2013-05-31 06:18:58

One obvious workaround for this bug is to not use auto-layout but I am loathe to do that. Any other workarounds? It seems like the constraint application code assumes that the scroll offset will be zero. To combat that, I tried intercepting layoutSubviews and setting the contentOffset to 0,0 before the constraints were applied, but sadly this had no effect.

@phatmann 2013-05-31 06:41:17

This answer stackoverflow.com/a/13326309/201828 has half of the right idea: zero out the contentOffset in viewDidDisappear. But if you try to restore the offset in viewWillAppear, the workaround fails. You can restore the offset in viewDidAppear. but this looks bad and I do not recommend it. Some posters suggested restoring the offset in viewDidLayoutSubviews, but that is not getting called me after the modal view is dismissed.

@Peter 2014-07-01 18:03:00

The radar link above shows as closed as a dup of a non-existent other radar :-(. One of the dupes has what solved it for me: "If we save the content offset to a property in viewWillAppear: then reset it to CGPointZero, then in viewDidLayoutSubviews put it back to the previous offset, the view behaves as expected." openradar.io/13942147

@matt 2014-07-01 18:31:54

@Peter Wow, what an insane dance. - My bug report to Apple (13648613) remains open... I have not tried it in iOS 8 yet.

@rattletrap99 2014-12-12 20:08:29

@matt-- I'm getting ready to try fixing the massive break introduced into my animation code by iOS 8 (framed-based, worked perfectly in iOS 7, no longer works since iOS 8). I'm now pretty freaked about how to proceed since finding this thread. My animation involves programmatically-created 'UIViews' in a 'UIScrollView', animated via 'animateWithDuration'. Have you gotten a resolution from Apple?

@matt 2014-12-12 20:10:29

@rattletrap99 That doesn't sound relevant to this question. There certainly is new view animation behavior in iOS 8 and it can certainly cause breakage, but it has nothing to do with scroll view autolayout. The incorrect scroll view layout bug was fixed long ago (during iOS 8 beta process). If you have a new question, ask a new question!

@rattletrap99 2014-12-12 20:35:59

I asked because the whole process of switching from frame-based to constraint-based animation is new and daunting to me, and my research led me here. The discussion regarding scrollView seemed to intimate yet another potential complication (or top of the other new stuff I'm trying to get my head around). Anyway, thanks for the clarification!

@matt 2014-12-12 21:49:21

@rattletrap99 But frame-based vs. constraint-based animation was just as much the case in iOS 7 and iOS 6. It is not new. Animation and autolayout have always been enemies. It's a huge problem: autolayout was introduced without considering it sufficiently, and Apple has been sweeping the damage under the rug ever since. See the rant in my book: apeth.com/iOSBook/ch17.html#_animation_and_autolayout

@matt 2014-12-12 21:50:43

@rattletrap99 And see my related essay here: stackoverflow.com/questions/12943107/…

@rattletrap99 2014-12-12 22:16:09

Many thanks, @matt. This will obviously take me some time to digest, but the first couple of lines promise a lot of help. In case you're interested, here is my original question on this topic. It contains two brief videos demonstrating the behavior of my code under iOS 7.1 vs 8.1. Drastic, and unnerving, since I was modestly proud of the animation I'd achieved under 7.1. Anyway, thanks again for your generosity in sharing your wisdom!

@rattletrap99 2014-12-12 23:05:56

Sorry--[here's the link to that question] (stackoverflow.com/questions/27385681/…) and the videos.

@matt 2014-12-12 23:35:56

@rattletrap99 Aha. I think one big change here that accounts for the difference in behavior is that in iOS 8 setting a label's text triggers layout immediately, whereas in iOS 7 and before it did not. See my answer here: stackoverflow.com/a/26964376/341994 However, you were always playing fast and loose, doing a lot of risky stuff inside an animation block that should not have been done there.

@rattletrap99 2014-12-13 02:15:33

Thanks for looking, @matt! I'm a fledgling, and I appreciate you pointing out the extra stuff in the animation block. I clearly have a major rewrite in front of me. I'll check your link now.

@Lucien 2015-01-16 12:57:17

Thanks, That iOS 6 Release notes explains it all.

@Ollie Strevel 2019-06-10 21:40:37

The only answer that works for me. Thank you!

@n8tr 2015-01-22 03:47:26

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.

@phatmann 2013-04-16 04:50:10

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.

@pgpb.padilla 2013-04-20 04:05:00

This is perfect. I have been looking for a simple example like the one in the link. Thank you!!!

@dmur 2013-10-29 22:16:12

While matt's answer is good, this one is much more practically helpful for solving the issues I have had with using it

@matt 2014-03-27 17:29:24

@dmur "While matt's answer is good, this one is much more practically helpful" - Dude, this is also my answer. He got the code/explanation from my book! Glad I was able to help twice. :)))

@Yogesh Maheshwari 2014-05-20 15:18:56

This is the only thing that worked.

@ArtSabintsev 2014-09-08 23:20:39

Depending on how you lay out your scrollView and their subviews, you may need to pin your stuff to the left or top. In my case, I had to pin everything to the left.

@Moisés Olmedo 2015-05-18 18:59:14

You can also add the constraint via the Interface Builder. Great answer!

@JustLearningAgain 2012-11-24 05:55:13

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.

@matt 2012-11-25 03:37:47

But UIScrollView is special, and your answer fails to take that fact into account.

Related Questions

Sponsored Content

27 Answered Questions

[SOLVED] UIScrollView Scrollable Content Size Ambiguity

8 Answered Questions

[SOLVED] iOS: Multi-line UILabel in Auto Layout

3 Answered Questions

5 Answered Questions

[SOLVED] UITextView inside UIScrollView with AutoLayout

6 Answered Questions

[SOLVED] autolayout - make height of view relative to half superview height

  • 2013-02-18 12:01:43
  • Mete
  • 84489 View
  • 130 Score
  • 6 Answer
  • Tags:   ios autolayout

6 Answered Questions

2 Answered Questions

1 Answered Questions

3 Answered Questions

[SOLVED] UIScrollView, Autolayout and subviews

1 Answered Questions

Sponsored Content