iOS8 使用 Interface Builder 自动调整静态 TableView 单元格
iOS8 self-sizing static TableView cells with Interface Builder
我很高兴能够在 Xcode 内构建我的静态 TableView,使用自动布局支持动态类型,如 WWDC2014 What's New in Table and Collection Views 中所述。
我宁愿严格使用 Xcode / Interface Builder 和故事板来处理自动布局。当我这样做时,不知何故 TableView 单元格没有调整大小,我确定我遗漏了一些简单的东西。
要重现这一点,使用 Xcode 7 beta 5,我:
- 创建了一个新的单视图项目。
- 将 Storyboard 入口点设置为新的 UITableViewController。
- 使其成为具有分组样式的静态 table 视图。
- 在第一行添加了一个标签。添加了顶部、底部、左侧和右侧的约束。
- 设置标签字体为"Body"。
已添加到 ViewDidLoad:
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0;
运行 它并在设置中调整动态类型。字体更改时,TableView 高度仍停留在明显的默认值 44 并截断标签。
这是上面的结果GitHub repository。
为什么自动布局不会导致 TableView 扩展以填充必要的 space 以适应新的更大的标签文本?
我发现了一些关于这个主题的很棒的帖子,例如下面的帖子,一心想使用代码来设置约束 here。
我没有找到任何在纯 Interface Builder 中执行此操作的示例。当然这很有可能?
更新
我更新了 GitHub 源代码以包含第二个 table 行,其中包含 ImageView 而不是 UILabel;它显示相同的问题:
此外,当我在标签或图像视图上设置明确的高度约束时,我生成了以下内容。问题似乎是我没有设置的 "UIView-Encapsulated-Layout-Height" 约束。我猜它的生成是因为在我的 IB 静态 table 视图中,行高设置(默认)为 44。
Unable to simultaneously satisfy constraints.
...
"<NSLayoutConstraint:0x7fa371f39e30 V:[UILabel:0x7fa371f38d30'Label'(20)]>",
"<NSLayoutConstraint:0x7fa371c39160 UILabel:0x7fa371f38d30'Label'.top == UITableViewCellContentView:0x7fa371e17dc0.topMargin>",
"<NSLayoutConstraint:0x7fa371c393c0 UITableViewCellContentView:0x7fa371e17dc0.bottomMargin == UILabel:0x7fa371f38d30'Label'.bottom>",
"<NSLayoutConstraint:0x7fa371f41a40 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fa371e17dc0(43.5)]>"
但是 ViewDidLoad 中的这个不应该覆盖这个吗?
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0;
自动调整 table 视图单元格是否不能与静态 table 视图一起使用?
更新 2
我使用动态原型而不是静态 table 视图构建了同样的东西,并且一切正常:
它确实看起来确实是静态与动态原型 tables。静态 table 视图单元格未正确展开。
我在 WWDC 视频中没有看到动态与静态的提及,所以此时我将其归因于一个错误。如果我学到任何新东西会更新。
我更新了上面的 GitHub 存储库以显示静态(损坏)和动态(工作)视图的示例。table。
我没有时间看代码,但我几乎可以肯定问题出在标签上。字体大小改变但标签的大小不变。我怀疑是因为文本在占据整行后没有被截断,所以它留下了一点余量。
做一个快速测试:为文本标签添加彩色背景。我敢打赌,您会发现它没有增长。如果没有,请看这里:Adjust UILabel height depending on the text
答案:
这是 Xcode7b5 中的错误。我刚刚按照 Xcode 6.4 和 Xcode 7b5.
中的相同步骤确认了这一点
- 创建新的单视图应用程序
- 新文件。 Cocoa Class "MyStaticTableViewController", UITableViewController.
的子类
- 在 Storyboard 中,拖入新的 Table View Controller。
- 将 Class 更改为 MyStaticTableViewController。
- 将故事板入口点拖到新的 VC。
- 删除原来的VC。
- 将 Class 更改为 MyStaticTableViewController 以获得新的 VC。
- Select Table 视图。将内容更改为静态单元格并将样式更改为分组。
- 将新标签拖到第一个 Table 查看单元格。将字体更改为正文。将顶部、底部、左侧、右侧约束设置为 0 并更新帧。
- 在MyStaticTableViewController.m中添加:
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0;
}
- 使用动态类型验证增加大小会导致 table 行也扩展。
Xcode 6.4 创建的项目按预期工作 - table 视图单元格展开以适合标签。
Xcode7b5 创建的项目如原问题所述失败。
有趣的是,如果用 Xcode7 打开 Xcode6 项目,它也能正常工作。这与 Xcode7 如何创建项目或故事板有关。
更新
我将 .storyboard 文件相互比较,在损坏的 Xcode7b5 中 tableView 条目下,有一个 rect 定义:
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
我删除了这一行,看来 table 视图单元格现在可以正确地自动调整大小了!
更新 2
关键问题似乎是 XML 文件中每个 "tableViewCell" 条目下留下的 "rect" 条目。解决这些问题是解决问题的方法。
更新 3
归档雷达:
"Engineering has determined that your bug report (22311571) is a duplicate of another issue (17995201) and will be closed."
对于静态 table 视图单元格,您不能在 ViewDidLoad 中使用 UITableViewAutomaticDimension。相反,使用覆盖函数 heightForRowAt。我的 viewDidLoad 里面什么都没有。我在 ViewDidLoad 上面添加了这两个覆盖函数。
//第一个覆盖每行的高度,以便自动调整大小。
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
//这给出了调整大小之前行的高度的估计值
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
只要您有顶部、底部、左侧和右侧布局约束,所有内容都应该调整大小。
我很高兴能够在 Xcode 内构建我的静态 TableView,使用自动布局支持动态类型,如 WWDC2014 What's New in Table and Collection Views 中所述。
我宁愿严格使用 Xcode / Interface Builder 和故事板来处理自动布局。当我这样做时,不知何故 TableView 单元格没有调整大小,我确定我遗漏了一些简单的东西。
要重现这一点,使用 Xcode 7 beta 5,我:
- 创建了一个新的单视图项目。
- 将 Storyboard 入口点设置为新的 UITableViewController。
- 使其成为具有分组样式的静态 table 视图。
- 在第一行添加了一个标签。添加了顶部、底部、左侧和右侧的约束。
- 设置标签字体为"Body"。
已添加到 ViewDidLoad:
self.tableView.rowHeight = UITableViewAutomaticDimension; self.tableView.estimatedRowHeight = 44.0;
运行 它并在设置中调整动态类型。字体更改时,TableView 高度仍停留在明显的默认值 44 并截断标签。
这是上面的结果GitHub repository。
为什么自动布局不会导致 TableView 扩展以填充必要的 space 以适应新的更大的标签文本?
我发现了一些关于这个主题的很棒的帖子,例如下面的帖子,一心想使用代码来设置约束 here。
我没有找到任何在纯 Interface Builder 中执行此操作的示例。当然这很有可能?
更新
我更新了 GitHub 源代码以包含第二个 table 行,其中包含 ImageView 而不是 UILabel;它显示相同的问题:
此外,当我在标签或图像视图上设置明确的高度约束时,我生成了以下内容。问题似乎是我没有设置的 "UIView-Encapsulated-Layout-Height" 约束。我猜它的生成是因为在我的 IB 静态 table 视图中,行高设置(默认)为 44。
Unable to simultaneously satisfy constraints.
...
"<NSLayoutConstraint:0x7fa371f39e30 V:[UILabel:0x7fa371f38d30'Label'(20)]>",
"<NSLayoutConstraint:0x7fa371c39160 UILabel:0x7fa371f38d30'Label'.top == UITableViewCellContentView:0x7fa371e17dc0.topMargin>",
"<NSLayoutConstraint:0x7fa371c393c0 UITableViewCellContentView:0x7fa371e17dc0.bottomMargin == UILabel:0x7fa371f38d30'Label'.bottom>",
"<NSLayoutConstraint:0x7fa371f41a40 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fa371e17dc0(43.5)]>"
但是 ViewDidLoad 中的这个不应该覆盖这个吗?
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0;
自动调整 table 视图单元格是否不能与静态 table 视图一起使用?
更新 2
我使用动态原型而不是静态 table 视图构建了同样的东西,并且一切正常:
它确实看起来确实是静态与动态原型 tables。静态 table 视图单元格未正确展开。
我在 WWDC 视频中没有看到动态与静态的提及,所以此时我将其归因于一个错误。如果我学到任何新东西会更新。
我更新了上面的 GitHub 存储库以显示静态(损坏)和动态(工作)视图的示例。table。
我没有时间看代码,但我几乎可以肯定问题出在标签上。字体大小改变但标签的大小不变。我怀疑是因为文本在占据整行后没有被截断,所以它留下了一点余量。
做一个快速测试:为文本标签添加彩色背景。我敢打赌,您会发现它没有增长。如果没有,请看这里:Adjust UILabel height depending on the text
答案:
这是 Xcode7b5 中的错误。我刚刚按照 Xcode 6.4 和 Xcode 7b5.
中的相同步骤确认了这一点- 创建新的单视图应用程序
- 新文件。 Cocoa Class "MyStaticTableViewController", UITableViewController. 的子类
- 在 Storyboard 中,拖入新的 Table View Controller。
- 将 Class 更改为 MyStaticTableViewController。
- 将故事板入口点拖到新的 VC。
- 删除原来的VC。
- 将 Class 更改为 MyStaticTableViewController 以获得新的 VC。
- Select Table 视图。将内容更改为静态单元格并将样式更改为分组。
- 将新标签拖到第一个 Table 查看单元格。将字体更改为正文。将顶部、底部、左侧、右侧约束设置为 0 并更新帧。
- 在MyStaticTableViewController.m中添加:
- (void)viewDidLoad { [super viewDidLoad]; self.tableView.rowHeight = UITableViewAutomaticDimension; self.tableView.estimatedRowHeight = 44.0; }
- 使用动态类型验证增加大小会导致 table 行也扩展。
Xcode 6.4 创建的项目按预期工作 - table 视图单元格展开以适合标签。
Xcode7b5 创建的项目如原问题所述失败。
有趣的是,如果用 Xcode7 打开 Xcode6 项目,它也能正常工作。这与 Xcode7 如何创建项目或故事板有关。
更新
我将 .storyboard 文件相互比较,在损坏的 Xcode7b5 中 tableView 条目下,有一个 rect 定义:
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
我删除了这一行,看来 table 视图单元格现在可以正确地自动调整大小了!
更新 2
关键问题似乎是 XML 文件中每个 "tableViewCell" 条目下留下的 "rect" 条目。解决这些问题是解决问题的方法。
更新 3
归档雷达:
"Engineering has determined that your bug report (22311571) is a duplicate of another issue (17995201) and will be closed."
对于静态 table 视图单元格,您不能在 ViewDidLoad 中使用 UITableViewAutomaticDimension。相反,使用覆盖函数 heightForRowAt。我的 viewDidLoad 里面什么都没有。我在 ViewDidLoad 上面添加了这两个覆盖函数。
//第一个覆盖每行的高度,以便自动调整大小。
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
//这给出了调整大小之前行的高度的估计值
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
只要您有顶部、底部、左侧和右侧布局约束,所有内容都应该调整大小。