【发布时间】: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 ==>"
)
在这种特殊情况下,我注意到我的<tableViewCell> 没有<rect> 标签,这就是它输出height== 的原因。 (更多关于<rect>标签的信息...)
问题
- 是否需要在 cellForRow 中调用 setNeedsUpdateConstraints 和 updateConstraintsIfNeeded?如果是这样,那是为什么?我没有以编程方式更新任何约束。我之前创建了项目,在 UITableViewCells 内部调整了多行标签的大小,如果没有该代码,这些标签看起来很完美。
<rect> 标签的奇怪行为
这似乎与<tableViewCell> 中<rect> 标记的奇怪行为有关。具体来说,它可能存在也可能不存在,如果存在,它的高度可能会设置为奇怪的值,这可能会导致问题。
以下是我注意到的一些奇怪行为...
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 从 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>
在大小检查器中将“默认”显示为行高。
注意有一个<rect> 标签,它选择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,我们仍然在 <rect> 标签中得到 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" 属性添加到 <tableViewCell> 标记,但保持 <rect> 不变:
<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。创建一个全新的主从项目
这会创建一个<rect> 标签:
<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 创建模板,我们都会得到完全相同的结果。
总结
<rect> 标签是否已创建?
- 创建 UITableViewController:否
- 从主从模板创建项目:是
- 从对象库中拖动 UITableViewCell:是
问题
- 应该存在rect标签吗?
- 如果是这样,应该将高度设置为多少?
- 有没有办法通过Interface Builder添加/删除/修改rect标签而不直接接触xml?
对于我的原始单元格,这是我手动更改 rect 标记时发生的情况:
A.如果我完全删除 <rect> 标签
输出:
Unable to simultaneously satisfy constraints ...
"<NSLayoutConstraint:0x7fb51430b220 UITableViewCellContentView:0x7fb514309340.height ==>"
B.将<rect> 设置为较小的高度
如果我将值设置为 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.将<rect> 设置为较大的高度
如果我将 rect 设置为 65 以上的值,它不会向控制台输出任何内容。
在这个测试中,我使用了:
<rect key="frame" x="0.0" y="0.0" width="600" height="999"/>
除了不输出约束警告之外,一切看起来都是正确的。
问题
- 我如何知道在任何给定单元格上设置哪个值?
我将很快创建一个显示这些问题的示例项目。
【问题讨论】:
标签: uitableview storyboard ios8 autolayout