意外 NSAutoresizingMaskLayoutConstraint 的 AutoLayout 约束问题

AutoLayout constraint issue with unexpected NSAutoresizingMaskLayoutConstraint(意外 NSAutoresizingMaskLayoutConstraint 的 AutoLayout 约束问题)

本文介绍了意外 NSAutoresizingMaskLayoutConstraint 的 AutoLayout 约束问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我在 https://github.com/nicolasccit/AutoLayoutCellWarning

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

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

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

我得到以下异常:

可能至少以下列表中的一个约束是您不想要的.试试这个:(1)查看每个约束并尝试找出您不期望的;(2) 找到添加了一个或多个不需要的约束的代码并修复它.(注意:如果您看到不理解的 NSAutoresizingMaskLayoutConstraints,请参阅 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档)("<NSLayoutConstraint:0xa6e4f90 V:[UIImageView:0xa6e4340]-(10)-|(名称:'|':UITableViewCellContentView:0xa6e4150)>","<NSLayoutConstraint:0xa6e4f10 V:[UIImageView:0xa6e4340(80)]>","<NSLayoutConstraint:0xa6e4ed0 V:|-(10)-[UIImageView:0xa6e4340] (名称: '|':UITableViewCellContentView:0xa6e4150)>","<NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]>")将尝试通过打破约束来恢复

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

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

我在以下位置看到了答案:自动布局约束问题UITableViewCell 中的 iOS7 但它们似乎都不适合我.

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

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

谢谢,尼古拉斯

解决方案

我已将您的代码的更正版本放在 https://github.com/mattneub/AutoLayoutCellWarning.完美运行.这条线是造成您麻烦的主要原因:

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

改成

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

一切都会好起来的.

您遇到问题的主要原因是,通过为图像视图分配绝对高度,您无法同时为单元格分配高度.浮点数不准确,因此您需要为单元格的增长/收缩留出一些空间.如果我们去掉绝对高度,图像视图会从其固有内容大小中获取高度,优先级较低,因此没有冲突.

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

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

请参阅在我的书中中对这个问题的讨论..p>

编辑(2014 年 5 月):不幸的是,我上面的回答未能指出导致此问题的关键原因之一,即 单元格分隔符具有高度(如果它尚未设置为无).因此,如果您为单元格分配的高度不考虑分隔符高度,则自动布局约束(如果是绝对约束)无法解析为该高度.(请参阅这个答案,这真的让我脑子里冒出了灯泡.)

I'm using auto layout constraints programmatically and I am constantly seeing the same kind of error across my application usually related to a constraint that looks like this:

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

I've put some sample code to reproduce at https://github.com/nicolasccit/AutoLayoutCellWarning

In this example, I am creating a very simple view with 2 UI elements: an image view called imageThumbnail and a label called labelName with some constraints:

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

On both elements I set the AutoresizingMaskIntoConstraints to NO.

And I am getting the following exception:

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 )>

I know the last constraint is related to the content view but I am unclear to properly remove it (Setting
AutoresizingMaskIntoConstraints to NO on the contentView raises an error and in the SO link below, it messes up the entire layout):

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

I've seen the answers at: Auto layout constraints issue on iOS7 in UITableViewCell but none of them seem to be working for me here.

I believe that the constraints I define are valid and pretty straightforward but can't seem to figure out what's going on. And I'm seeing the exception being raised both in iOS 6.1 and iOS 7.

Any idea what I am doing wrong here?

Thanks, Nicolas

解决方案

I've put a corrected version of your code at https://github.com/mattneub/AutoLayoutCellWarning. Works perfectly. This line was the main cause of your trouble:

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

Change that to

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

And all will be well.

The main reason you were having trouble is that by assigning an absolute height to the image view, you were making it impossible to also assign a height to the cell. Floating point is not exact, so you need to allow some room for the cell to grow / shrink. If we take away the absolute height, the image view gets its height from its intrinsic content size, at a lower priority, so there is no conflict.

I have some other critiques of your code. In trying to do dynamic setting of the cell's height while using auto layout, you were giving layout and constraint update commands you should never be giving, and you are giving them at wrong times. It is possible to do dynamic row heights based on constraints, but the way you're doing it is not the way. All you have to do is call systemLayoutSizeFittingSize to find out the correct cell height. Also, there is absolutely no need to put your "hidden" cell into the interface. Don't do that; it just confuses things. One of the things you'll notice when you look at my version of the code is that it is much simpler than yours, because of those differences.

For a working method, see my example at https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch08p424variableHeights/ch21p722variableHeights/RootViewController.m

And see the discussion of this issue in my book.

EDIT (May 2014): Unfortunately my answer above fails to point out one of the key causes of this problem, namely, that the cell separator has height (if it hasn't been set to None). Therefore if you assign the cell a height that doesn't take the separator height into account, the auto layout constraints, if absolute, cannot be resolved into that height. (See this answer, which really made the lightbulb come on inside my head.)

这篇关于意外 NSAutoresizingMaskLayoutConstraint 的 AutoLayout 约束问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:意外 NSAutoresizingMaskLayoutConstraint 的 AutoLayout 约束问题

基础教程推荐