AutoLayout约束问题与意外的NSAutoresizingMaskLayoutConstraint

我以编程方式使用自动布局约束,并且经常在我的应用程序中看到相同types的错误,通常与约束如下所示:

"<NSAutoresizingMaskLayoutConstraint:0x82da910 h=--& v=--& V:[UITableViewCellContentView:0x82d9fb0(99)]>" 

我已经把一些示例代码重现在https://github.com/nicolasccit/AutoLayoutCellWarning

在这个例子中,我使用2个UI元素创build了一个非常简单的视图:一个名为imageThumbnail的图像视图和一个名为labelName的标签,带有一些约束条件:

 "H:|-padding-[_imageThumbnail(==imageWidth)]-[_labelName]"; "V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|"; "V:|-padding-[_labelName]"; 

在这两个元素上,我将AutoresizingMaskIntoConstraints设置为NO。

我得到以下例外:

 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:0xa6e4f90 V:[UIImageView:0xa6e4340]-(10)-| (Names: '|':UITableViewCellContentView:0xa6e4150 )>", "<NSLayoutConstraint:0xa6e4f10 V:[UIImageView:0xa6e4340(80)]>", "<NSLayoutConstraint:0xa6e4ed0 V:|-(10)-[UIImageView:0xa6e4340] (Names: '|':UITableViewCellContentView:0xa6e4150 )>", "<NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0xa6e4f90 V:[UIImageView:0xa6e4340]-(10)-| (Names: '|':UITableViewCellContentView:0xa6e4150 )> 

我知道最后一个约束与内容视图有关,但我不清楚是否要删除它(设置
在contentView上将AutoresizingMaskIntoConstraints设置为NO会引发一个错误,并在下面的SO链接中混淆整个布局):

 <NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]> 

我已经看到了答案: UITableViewCell中的iOS7自动布局约束问题,但他们都没有在我这里工作。

我相信我所定义的约束是有效的,非常简单,但似乎无法弄清楚发生了什么。 而且我看到在iOS 6.1和iOS 7中都出现exception。

任何想法我在这里做错了吗?

谢谢,尼古拉斯

我已经在https://github.com/mattneub/AutoLayoutCellWarning上提供了一个更正的代码版本&#x3002; 完美的作品。 这条线是你麻烦的主要原因:

 NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|"; 

改变它

 NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail]-padding-|"; 

一切都会好的。

你遇到麻烦的主要原因是,通过给图像视图指定一个绝对高度,你不可能为单元指定一个高度。 浮点不是精确的,所以你需要为单元格增长/缩小留出一些空间。 如果我们拿走了绝对高度,图像视图就会从内在的内容大小中获得高度,优先级较低,所以没有冲突。

我还有一些其他批评你的代码。 在尝试使用自动布局进行单元格高度的dynamic设置时,您正在给出您不应该给出的布局和约束更新命令,并且在错误的时间给它们。 有可能根据约束来做dynamic行高,但是你做这件事的方式不是这样。 你所要做的就是调用systemLayoutSizeFittingSize来找出正确的单元格高度。 而且,绝对不需要将“隐藏”单元放入界面。 不要那样做; 它只是混淆的东西。 当您查看我的代码版本时,您会注意到的一点是,由于这些差异,它比您的代码简单得多。

有关工作方法,请参阅我的示例https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch08p424variableHeights/ch21p722variableHeights/RootViewController.m

在我的书中看到这个问题的讨论。

编辑 (2014年5月):不幸的是我上面的答案没有指出这个问题的关键原因之一,即细胞分离器有高度 (如果它没有被设置为无)。 因此,如果将单元格的高度分配给不考虑分隔符高度,则自动布局约束(如果是绝对的)无法parsing为该高度。 (看到这个答案 ,真的让灯泡进来我的头。)

您应该更彻底地阅读例外说明:

 Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints 

总之,你看到的这个约束是由于一些UIView将它的translatesAutoresizingMaskIntoConstraints设置为YES 。 在这种情况下,我会怀疑这是单元格的内容视图,正如UITableViewCellContentView暗示的那样。

您可以通过将属性设置为NO来禁用它。

 cell.contentView.translatesAutoresizingMaskIntoConstraints = NO 

编辑:现在请记住,这是一个临时性的修复,很可能你的约束有一些其他的逻辑错误,例如约束单元格的contentView中的东西到单元格本身。 或者看似强迫contentView比单元大(因此大于其自动大小)。

例如,你的手机够高吗? 即它足够高,以便contentView是100pt高? 请注意, contentView必须高,可能不一定匹配单元格的高度。