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

时间:2015-08-17 12:24:52

标签: ios objective-c xcode autolayout uicollectionview

我遇到autolayout的问题,控制台报告了我在单元格中的图像视图出现问题:

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

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

编辑:毋庸置疑,所有元素,包括图像视图都在正确的位置(我调试帧并设置随机颜色)但图像直到刷新才显示...有时单元格不会全部显示

6 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

enter image description here

在第二个单元格中,禁用了一些约束。这意味着删除任何高度任意宽度的约束。因此,当您在iphone中运行应用程序时,该约束与您当前的约束冲突。

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

答案 2 :(得分:0)

观点:

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

不要让我们检查约束

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

image2在容器的topMargin下是71个点,因此容器底边下至少有21个点。

image1底部与容器底部对齐,因此它位于容器的底部边缘上方。

现在您的上一个约束垂直居中image1image2,因此显然会发生碰撞。

我很难知道你要做什么,但我想你应该只相对于容器定位image1image2的唯一垂直约束应该是那个垂直居中。

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

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

答案 3 :(得分:0)

尝试这个帮助我在控制台中删除那些约束中断。

yourCustomCell.contentView.frame = yourCustomCell.bounds;  

答案 4 :(得分:0)

检查你的imageView centerY约束

enter image description here

删除此约束... 由于约束歧义,会出现此问题。添加自动布局时,您必须将适当的自动布局约束应用于imageView。

在删除centreY约束后如果存在歧义,则xcode将再次显示相同的错误,同样您必须删除不明确的约束。

答案 5 :(得分:-1)

警告信息提供了错误的线索。

CSS

所以要分析你有两个基于视图的对象。一个设置为自己从上到下居中到另一个视图(0x7fa9810375d0到0x7fa981037490 - 这些是视图ID)

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

table.scroll {
    width: 100%;
    /* Optional */
    /* border-collapse: collapse; */
    border-spacing: 0;
    border: 2px solid black;
}
table.scroll tbody, table.scroll thead {
    display: block;
}
thead tr th {
    height: 30px;
    line-height: 30px;
    /*text-align: left;*/
}
table.scroll tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}
tbody {
    border-top: 2px solid black;
}
tbody td, thead th {
    width:auto;
    /* Optional */
    border-right: 1px solid black;
}
tbody td:last-child, thead th:last-child {
    border-right: none;
}

看起来像0x7fa981037490的顶部正对齐到视图顶部0x7fa9810371d0加71点。

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

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

试一试。让我知道