【问题标题】:iOS 8 UITableViewCell resizing outputting "Unable to simultaneously satisfy constraints"iOS 8 UITableViewCell 调整大小输出“无法同时满足约束”
【发布时间】:2014-11-28 00:33:24
【问题描述】:

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

作为参考,单元格的高度为 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 ==>"
)

在这种特殊情况下,我注意到我的&lt;tableViewCell&gt; 没有&lt;rect&gt; 标签,这就是它输出height== 的原因。 (更多关于&lt;rect&gt;标签的信息...)

问题

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

&lt;rect&gt; 标签的奇怪行为

这似乎与&lt;tableViewCell&gt;&lt;rect&gt; 标记的奇怪行为有关。具体来说,它可能存在也可能不存在,如果存在,它的高度可能会设置为奇怪的值,这可能会导致问题。

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

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>

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

注意没有&lt;rect&gt;标签。

2。将 UITableViewCell 从 Object Library 拖到该表视图控制器中,创建它的方式如下:

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

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

注意有一个&lt;rect&gt; 标签,它选择44 作为它的高度。 44 恰好是 Size Inspector 中 table view 的 Row Height 的默认值。

3。将 Table View 的 Size Inspector 中的 Row Height 属性更改为 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" 来自rowHeight="44"

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

即使表格视图的行高现在是 100,我们仍然在 &lt;rect&gt; 标签中得到 44 的高度:

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

5。调整情节提要中的单元格大小,使其在视觉上更小(至 55)

这会将新的 rowHeight="55" 属性添加到 &lt;tableViewCell&gt; 标记,但保持 &lt;rect&gt; 不变:

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

如果您在 Size Inspector 中查看 Row Height 属性,它现在显示的是 55,而不是“默认”。

6。创建一个全新的主从项目

这会创建一个&lt;rect&gt; 标签:

<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"/>

请注意,即使故事板使用尺寸等级,因此所有内容都是 600 宽度,但它仍然选择了 320 宽度。另请注意,无论我们选择为 iPhone 还是 Universal 创建模板,我们都会得到完全相同的结果。

总结

&lt;rect&gt; 标签是否已创建?

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

问题

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

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

A.如果我完全删除 &lt;rect&gt; 标签

输出:

Unable to simultaneously satisfy constraints ...
"<NSLayoutConstraint:0x7fb51430b220 UITableViewCellContentView:0x7fb514309340.height ==>"

B.将&lt;rect&gt; 设置为较小的高度

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

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

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

输出:

Unable to simultaneously satisfy constraints ...
"<NSLayoutConstraint:0x7fe3104ce760 UITableViewCellContentView:0x7fe3104e00d0.height == 44>"

C.将&lt;rect&gt; 设置为较大的高度

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

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

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

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

问题

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

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

【问题讨论】:

    标签: uitableview storyboard ios8 autolayout


    【解决方案1】:

    在完成动画后尝试添加:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-23
      相关资源
      最近更新 更多