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上提供了一个更正的代码版本。 完美的作品。 这条线是你麻烦的主要原因:
NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|";
改变它
NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail]-padding-|";
一切都会好的。
你遇到麻烦的主要原因是,通过给图像视图指定一个绝对高度,你不可能为单元指定一个高度。 浮点不是精确的,所以你需要为单元格增长/缩小留出一些空间。 如果我们拿走了绝对高度,图像视图就会从内在的内容大小中获得高度,优先级较低,所以没有冲突。
我还有一些其他批评你的代码。 在尝试使用自动布局进行单元格高度的dynamic设置时,您正在给出您不应该给出的布局和约束更新命令,并且在错误的时间给它们。 有可能根据约束来做dynamic行高,但是你做这件事的方式不是这样。 你所要做的就是调用systemLayoutSizeFittingSize
来找出正确的单元格高度。 而且,绝对不需要将“隐藏”单元放入界面。 不要那样做; 它只是混淆的东西。 当您查看我的代码版本时,您会注意到的一点是,由于这些差异,它比您的代码简单得多。
在我的书中看到这个问题的讨论。
编辑 (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
必须高,可能不一定匹配单元格的高度。
- 具有多个tableviews的iOS 6 AutoLayout全部dynamic高度
- 更正UITableViewHeaderFooterView的子类化和自动布局
- iOS Autolayout垂直等于填充父视图的空间
- UITableViewCell + Autolayout + RTL
- Google地图信息窗口根据内部内容resize
- AutoLayout的问题与在NIB文件中定义并在StoryBoard中使用的自定义视图
- 缩进UITableViewCell中的所有自动布局约束
- 子视图中的UIButton在NSLayoutConstraint后没有收到触摸
- 与ContentInset的UICollectionView不滚动一路下去