集合视图上奇怪的自动布局行为

Strange autolayout behaviour on collection views

我遇到自动布局问题,控制台报告单元格中的图像视图存在问题:

RefreshCatalogue[31754:16177989] 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:0x7fa98103b740 V:[UIImageView:0x7fa9810375d0]-(0)-|   (Names: '|':UIView:0x7fa9810371d0 )>",
    "<NSLayoutConstraint:0x7fa98103b7e0 V:|-(0)-[UIImageView:0x7fa9810375d0]   (Names: '|':UIView:0x7fa9810371d0 )>",
    "<NSLayoutConstraint:0x7fa98103b8d0 UIImageView:0x7fa9810375d0.centerY == UIImageView:0x7fa981037490.centerY>",
    "<NSLayoutConstraint:0x7fa98103ba60 UIImageView:0x7fa981037490.top == UIView:0x7fa9810371d0.topMargin + 71>",
    "<NSAutoresizingMaskLayoutConstraint:0x7fa980d44a10 h=--& v=--& V:[UIView:0x7fa9810371d0(50)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fa98103b8d0 UIImageView:0x7fa9810375d0.centerY == UIImageView:0x7fa981037490.centerY>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

问题是如果我这样做:

[self.collectionView reloadItemsAtIndexPaths:@[indexPath]];

即使图像视图似乎具有正确的框架,也没有显示任何内容,图像 属性 已设置。 如果我重新加载整个集合视图:

[self.collectionView reloadData];

错误仍然存​​在,但图像显示。代码在这里公开,有兴趣的可以看看: https://github.com/Ridiculous-Innovations/RefreshCatalogue

此外,故事板中的所有约束似乎都是蓝色的。知道可能导致问题的原因吗?

编辑:不用说所有元素,包括图像视图都在正确的位置(我调试了框架并设置了随机颜色)但是图像直到刷新才显示...有时单元格不显示根本不显示

嗯,警告信息给出了问题的线索。

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fa98103b8d0 UIImageView:0x7fa9810375d0.centerY == UIImageView:0x7fa981037490.centerY>

因此要分析您有两个基于视图的对象。一个设置为从上到下以另一个视图为中心(0x7fa9810375d0 到 0x7fa981037490 - 这些是视图 ID)

但视图 id 0x7fa981037490 也有另一个约束,

<NSLayoutConstraint:0x7fa98103ba60 UIImageView:0x7fa981037490.top == UIView:0x7fa9810371d0.topMargin + 71>

看起来 0x7fa981037490 的顶部与视图 0x7fa9810371d0 的顶部对齐加上 71 点。

我还没有下载你的项目,但我敢打赌这就是问题所在。最好的猜测是无法满足 centre.y 约束,因为顶部对齐将 ImageView 移动到破坏它的位置。尝试在脑海中直观地查看您在约束中设置的内容。您已经对齐到 ImageViews 并将其中一个对齐到另一个视图的边缘。怎么破? (这是你应该问自己的)

尝试一次删除一个约束并构建 运行。如果警告消失,那就是需要修复的地方。是的,视图可能看起来很奇怪,您可以使用 Command + Z 逐一撤消删除的约束。

试一试。让我知道

在第二个单元格中,一些约束被禁用。这意味着对于 Any Height Any Width 的约束被删除。因此,当您在 iphone 中 运行 应用程序时,该约束与您当前的约束冲突。

所以删除突出显示的禁用约束。

观看次数:

UIView:0x7fa9810371d0,暂且命名为container
UIImageView:0x7fa9810375d0,我们将其命名为image1
UIImageView:0x7fa981037490,我们将其命名为image2

不让我们检查约束

容器 height50,由自动调整大小指定。您的集合视图可能未指定高度。这很可能是在将单元格调整为您的集合视图布局指定的大小之前创建单元格时的大小。

image2 是容器 topMargin 下方的 71 点,因此它至少是容器底部边缘下方的 21 点。

image1 bottom 与容器底部对齐,因此它在容器底部边缘上方。

现在你的最后一个约束中心 image1image2 垂直,所以显然有碰撞。

很难知道你想做什么,但我想你应该只相对于容器定位 image1 并且 image2 的唯一垂直约束应该是居中的那些他们垂直。

要查看 Interface Builder 中的错误,请将单元格高度更改为 50,您会看到所有内容都已损坏。只有一些不必要的约束会导致调整大小冲突。

还有一些约束未安装当前大小 class。您可能 运行 模拟器上的应用程序大小不同 class 并且安装了它们。这意味着甚至还有一些额外的碰撞。

你对 UIImageView:0x7fa981037490.top == UIView:0x7fa9810371d0.topMargin + 71 和高度为 0 的父框架有疑问(因此 imageview 高度必须为负,但这是不允许的),如右在调用 dequeueReusableCell 方法之后。 这种情况下可能的解决方法是将嵌套视图中最底部约束的优先级从 1000 更改为 999(垂直 Space - catalogueHeaderCell - 图像视图和垂直 Space - catalogueCell - 信息视图)。

试试这个,它可以帮助我删除控制台中的那些约束中断。

yourCustomCell.contentView.frame = yourCustomCell.bounds;  

检查你的图片View centerY constrain

删除此约束... 这个问题是由于约束歧义而发生的。添加自动布局时,您必须对 imageView 应用适当的自动布局约束。

删除 centerY 约束后,如果存在歧义,那么 xcode 将再次显示相同的错误,您必须再次删除有歧义的约束。