UIScrollView 不使用自动布局约束

Posted

技术标签:

【中文标题】UIScrollView 不使用自动布局约束【英文标题】:UIScrollView doesn't use autolayout constraints 【发布时间】:2012-11-21 18:11:14 【问题描述】:

我在它后面有一个滚动视图和一个图像视图,我正在用笔尖填充它。我正在使用自动布局。我在两个视图上都有一个用于超级视图的底部空间和一个用于超级视图的顶部空间。图像视图完全符合我的要求。对于 iphone 5,这是我想要的。对于其他 iphone,它位于屏幕底部上方,因此可以正确调整大小。滚动视图在 iphone 5 上看起来正确,但在其他手机上它不会调整大小,因此它会向下滚动到应用程序视图的下方。我在日志中收到这些消息:

 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>

我已经试过了

[self setTranslatesAutoresizingMaskIntoConstraints:YES];

[self.myScrollView setTranslatesAutoresizingMaskIntoConstraints:YES];

据我所知,这只是消除了视图中的所有约束。这不是我想要的。

【问题讨论】:

Apple 的Technical Note TN2154: UIScrollView And Autolayout 详细介绍了这个问题。 【参考方案1】:

UIScrollView 和自动布局的关系不同于自动布局的其他方面。基本上,如果允许运行简单的自动布局,则不会滚动。例如,如果滚动视图的子视图以正常方式被固定到距离滚动视图顶部 10 个点的约束,那么它将绝对固定在那里;无论滚动视图如何滚动,它都不会移动。

为了解决这个问题,使用自动布局的 UIScrollView 以全新的方式运行。因此,当您说“我正在使用自动布局”时,您必须准备好让事情的运作方式与以前大不相同。您必须使用带有translatesAutoresizingMaskIntoConstraints = YES 和显式内容大小的单个滚动视图子视图,否则所有内容都必须具有translatesAutoresizingMaskIntoConstraints = NO,并且内容大小将根据子视图的约束隐式推导出。

这在https://developer.apple.com/library/content/releasenotes/General/RN-iosSDK-6_0/index.html中有很好的解释

【讨论】:

您可能对这个问题感兴趣:***.com/questions/14307037/…(尤其是因为赏金!)我认为这是一个滚动视图/自动布局问题,但在我看来,它读起来像一个错误 - 在这种情况下滚动视图是一个表格视图,内容大小在旋转时没有正确调整。 @matt 我不知道你是否见过这种行为,但是如果你只使用布局约束来定义滚动视图的内容大小,就会出现一个错误:滚动内容偏移远离 ( 0, 0) 移动到另一个选项卡或模态视图控制器,回来,滚动视图的子视图都被内容偏移量移动了,你不能回来。如果您能证实这一点并欺骗我的雷达,我将不胜感激:openradar.appspot.com/radar?id=2932404 @edelaney05 我想我可以确认这个错误,但在提交给 Apple 之前,您应该制作一个演示项目,尤其是。因为openradar.appspot.com/radar?id=2932404 中的复制粘贴代码甚至无法编译(您输入的constraintsWithVisualFormat:options:metrics:views: 名称错误)。始终使用实际有效的真实代码。此外,在实际项目中,您可以包含实际图像。苹果人没有想象力,没有时间;您必须提前为他们完成所有工作。 @edelaney05 "肩部意大利薄饼"???? :) 好的,很好。实际上,我根据他们的代码做了一个更紧密的,图像视图大小为一张大图。通过给滚动视图一个红色的背景颜色,并通过日志记录,很明显滚动视图认为一切都是正确的(内容大小,内容偏移),但是在错误的位置绘制图像视图,即偏移量离开视图时的内容偏移量。 @matt baconipsum.com ! :-) 惊人的。我看到的行为完全相同。滚动视图将所有内容报告为“正常”,但由于偏移量的原因绘制不正确。感谢您确认我没有发疯(但是,仅针对此错误!)。【参考方案2】:

在使用自动布局时非常重要:您必须将最后一个子视图的右侧和/或底部固定到滚动视图的右侧和/或底部。这就是滚动视图知道内容大小的方式。例如:

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

感谢this site 提供了完美的示例。

因此我失去了几个小时,我希望减轻其他人的痛苦。

【讨论】:

这是完美的。我一直在寻找一个简单的例子,比如链接中的例子。谢谢!!! 虽然马特的回答很好,但这个回答对解决我在使用它时遇到的问题更有实际帮助 @dmur “虽然马特的回答很好,但这个回答更实用” - 伙计,这也是我的回答。他从我的书中得到了代码/解释!很高兴我能帮助两次。 :))) 根据你如何布置你的滚动视图和它们的子视图,你可能需要把你的东西固定在左边或顶部。就我而言,我必须将所有内容都固定在左侧。 您也可以通过 Interface Builder 添加约束。很好的答案!【参考方案3】:

为了让 UIScrollviews 在约束条件下很好地工作,我使用这种方法回答了here。在那个答案中,我解决了如何让 vertically 滚动滚动视图工作,该滚动视图也适用于设备旋转。您也可以调整方法以使用 水平 滚动滚动视图。对于双向滚动的滚动视图,不要添加大小匹配宽度约束技巧。但其他一切都一样。

【讨论】:

【参考方案4】:

几件事。

    确保自动布局已打开(IB 在“文件检查器选项卡”上) 确保您没有进行任何涉及边界、框架等的更改 - 现在这一切都由自动约束完成 确保远离 AutoResizingMask。这将与您的新设置竞争。 如果这些都做对了,你现在可以布局你的按钮,它会很好用。方法如下。

此错误表明您的 nib 或该 nib 中的控件未使用自动布局。

【讨论】:

但是 UIScrollView 很特别,你的回答没有考虑到这个事实。

以上是关于UIScrollView 不使用自动布局约束的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 不使用自动布局约束

UIScrollView 不滚动 w/ 编程自动布局约束

UIView 不遵守 UIScrollView 中的自动布局约束

尽管添加了自动布局约束,但 UIScrollView 不滚动

UIScrollView 不能使用自动布局和动态约束滚动

Interface Builder 对 UIScrollView 的正确约束是啥?来自 IB 的纯自动布局