iOS 8 UITableViewCell调整输出大小"无法同时满足约束"

时间:2014-10-02 22:30:40

标签: uitableview storyboard ios8 autolayout

我在故事板中创建了一个UITableViewCell,并使用自动布局来定位所有内容,希望让iOS 8自动为我确定单元格高度。我的单元格有两个标签,其中一个是多行标签,首选宽度为自动。

作为参考,单元格的高度为208,但高度设置为“默认”。表格视图的行高设置为208。

在视图中加载,我运行以下代码:

self.tableView.estimatedRowHeight = 100;
self.tableView.rowHeight = UITableViewAutomaticDimension;

这在我第一次显示单元格时工作正常,一切正常显示。问题是如果一个单元被重用,它会不正确地拉伸。基于this post,我注意到我可能需要在cellForIndexPath中运行以下代码:

[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];

然而,当我添加该代码时,我收到消息:

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:0x7fd108dd1ce0 UITableViewCellContentView:0x7fd108d03d00.height ==>"
)

在这种特殊情况下,我注意到我的<tableViewCell>没有<rect>标记,这就是它输出height==的原因。 (有关<rect>标记下方的详情...)

问题

  • 我是否需要在cellForRow中调用setNeedsUpdateConstraints和updateConstraintsIfNeeded?如果是这样,为什么呢?我没有以编程方式更新任何约束。我之前已经创建了项目,在UITableViewCells内部调整了多行标签大小,看起来完全没有代码。

<rect>代码

的奇怪行为

这似乎与<rect><tableViewCell>标记的奇怪行为有关。具体来说,它可能存在也可能不存在,如果确实存在,其高度可能会设置为奇怪的值,这可能会引起问题。

以下是我注意到的一些奇怪行为......

1。从对象库中拖动一个全新的UITableViewController会创建一个单元格,如下所示:

<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="VVy-eG-5ZD">
    <autoresizingMask key="autoresizingMask"/>
    <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="VVy-eG-5ZD" id="o4d-7b-psa">
        <autoresizingMask key="autoresizingMask"/>
    </tableViewCellContentView>
</tableViewCell>

在“大小”检查器中将“默认”显示为行高。

注意没有<rect>标记。

2。将UITableViewCell从对象库拖动到该表视图控制器中将按如下方式创建它:

<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="SxR-MB-xdu">
    <rect key="frame" x="0.0" y="0.0" width="600" height="44"/>
    <autoresizingMask key="autoresizingMask"/>
    <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="SxR-MB-xdu" id="JDB-Ys-OoE">
        <autoresizingMask key="autoresizingMask"/>
    </tableViewCellContentView>
</tableViewCell>

在“大小”检查器中将“默认”显示为行高。

注意如何有一个<rect>标签,并选择44作为其高度。 44恰好是Size Inspector中表视图的行高的默认值。

3。将表视图的大小检查器中的行高属性更改为100。

细胞在视觉上变得更大,但它们的xml不受影响。

作为参考,以下是TABLE VIEW的xml之前的样子:

<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="qea-mf-mRA">
    <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>

......以下是它的样子:

<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="100" sectionHeaderHeight="22" sectionFooterHeight="22" id="qea-mf-mRA">
    <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>

唯一改变的是来自rowHeight="100"的{​​{1}}。

4。将另一个单元格从对象库拖到表视图

即使表格视图的行高现在为100,我们仍然会在rowHeight="44"标记中获得44高度:

<rect>

5。调整Storyboard中的单元格大小以使其在视觉上更小(至55)

这会为<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="wcV-YB-1eG"> <rect key="frame" x="0.0" y="0.0" width="600" height="44"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="wcV-YB-1eG" id="xM8-zX-Nrh"> <autoresizingMask key="autoresizingMask"/> </tableViewCellContentView> </tableViewCell> 标记添加新的rowHeight="55"属性,但保持<tableViewCell>不变:

<rect>

如果你在Size Inspector中查看Row Height属性,它现在显示为55,而不是“Default”。

6。创建一个全新的Master Detail Project

这会创建一个<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="55" id="wcV-YB-1eG"> <rect key="frame" x="0.0" y="0.0" width="600" height="44"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="wcV-YB-1eG" id="xM8-zX-Nrh"> <autoresizingMask key="autoresizingMask"/> </tableViewCellContentView> </tableViewCell> 标记:

<rect>

注意即使故事板使用大小类,因此一切都是600宽度,它仍然选择320宽度。另请注意,无论我们选择为iPhone还是Universal创建模板,我们都会得到相同的结果。

摘要

是否已创建<tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="2pz-XF-uhl" style="IBUITableViewCellStyleDefault" id="m0d-ak-lc9"> <rect key="frame" x="0.0" y="86" width="320" height="44"/> <autoresizingMask key="autoresizingMask"/> 代码?

  • 创建UITableViewController:否
  • 从主 - 明细模板创建项目:是
  • 从对象库中拖动UITableViewCell:是

问题

  • 矩形标签应该存在吗?
  • 如果是这样,高度应该设定为什么?
  • 有没有办法通过Interface Builder添加/删除/修改rect标签而不直接触摸xml?

对于我的原始单元格,这是手动更改rect标记时发生的情况:

一种。如果我完全删除<rect>标记

输出:

<rect>

B中。将Unable to simultaneously satisfy constraints ... "<NSLayoutConstraint:0x7fb51430b220 UITableViewCellContentView:0x7fb514309340.height ==>" 设置为较小的高度

如果我将值设置为1到65之间的任何值,我会收到以下错误消息。

在这个测试中,我使用了:

<rect>

输出:

<rect key="frame" x="0.0" y="0.0" width="600" height="44"/>

℃。将Unable to simultaneously satisfy constraints ... "<NSLayoutConstraint:0x7fe3104ce760 UITableViewCellContentView:0x7fe3104e00d0.height == 44>" 设置为较大的高度

如果我将rect设置为65以上,它就不会向控制台输出任何内容。

在这个测试中,我使用了:

<rect>

除了不输出约束警告外,一切看起来都是正确的。

问题

  • 如何知道在任何给定单元格上设置哪个值?

我将创建一个示例项目,很快就会显示这些问题。

1 个答案:

答案 0 :(得分:0)

在完成动画时尝试添加:

[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
[cell layoutIfNeeded];