意外的NSAutoresizingMaskLayoutConstraint的AutoLayout约束问题

nic*_*cit 15 objective-c uitableview ios autolayout

我正在以编程方式使用自动布局约束,并且我经常在我的应用程序中看到同样的错误,通常与看起来像这样的约束相关:

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

我在https://github.com/nicolasccit/AutoLayoutCellWarning上放了一些示例代码来重现

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

"H:|-padding-[_imageThumbnail(==imageWidth)]-[_labelName]";
"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|";
"V:|-padding-[_labelName]";
Run Code Online (Sandbox Code Playgroud)

在这两个元素上,我将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 )>
Run Code Online (Sandbox Code Playgroud)

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

<NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]>
Run Code Online (Sandbox Code Playgroud)

我已经看到了答案:UITableViewCell上的iOS7上的自动布局约束问题,但它们似乎都不适合我.

我相信我定义的约束是有效且非常简单的,但似乎无法弄清楚发生了什么.而且我看到iOS 6.1和iOS 7都引发了异常.

知道我在这里做错了什么吗?

谢谢,尼古拉斯

Hen*_*mak 8

您应该更彻底地阅读异常描述:

Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints
Run Code Online (Sandbox Code Playgroud)

简而言之,您所看到的这种约束是由于某些UIView将其translatesAutoresizingMaskIntoConstraints设置为YES.在这种情况下,我怀疑这是细胞的内容视图,正如暗示的那样UITableViewCellContentView.

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

cell.contentView.translatesAutoresizingMaskIntoConstraints = NO
Run Code Online (Sandbox Code Playgroud)

编辑:现在,请记住,这是一个临时修复,很可能您的约束有一些其他逻辑错误,例如contentView将单元格中的某些内容约束到单元格本身.或者通过看似强迫contentView比单元更大(因此比它的'自动尺寸更大).

例如,你的细胞足够高吗?即足够高,以至于contentView高100?请注意,contentView必须高,可能不一定与单元格的高度匹配.


mat*_*att 5

我已将更正的代码版本放在https://github.com/mattneub/AutoLayoutCellWarning上.完美的工作.这条线是你遇到麻烦的主要原因:

NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|";
Run Code Online (Sandbox Code Playgroud)

改为

NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail]-padding-|";
Run Code Online (Sandbox Code Playgroud)

一切都会好的.

您遇到麻烦的主要原因是,通过为图像视图指定绝对高度,您无法为单元格指定高度.浮点不精确,因此您需要为单元格增加/缩小留出一些空间.如果我们取消绝对高度,图像视图将从其内在内容大小获得高度,优先级较低,因此不存在冲突.

我对你的代码有一些其他批评.在使用自动布局时尝试动态设置单元格的高度时,您提供了您永远不应该给出的布局和约束更新命令,并且您在错误的时间给出它们.可以根据约束来执行动态行高,但是您执行此操作的方式并非如此.您所要做的就是打电话systemLayoutSizeFittingSize找出正确的细胞高度.此外,绝对不需要将"隐藏"单元格放入界面中.不要那样做; 它只会混淆事物.一,当你看我的版本的代码,你会注意到的事情是,它是很多的,因为这些分歧比你更简单.

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

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

编辑(2014年5月):不幸的是,我上面的回答没有指出这个问题的一个关键原因,即细胞分离器有高度(如果它没有设置为无).因此,如果为单元格指定不考虑分隔符高度的高度,则无法将自动布局约束(如果为绝对)解析为该高度.(看到这个答案,真的让灯泡在我脑海里浮现.)