具有静态表的动态类型和自定尺寸单元

我有一个典型的主 – 详细应用程序,允许用户浏览滚动的对象列表,然后使用push segue钻取到任何特定对象的详细信息。 滚动主列表是使用原型单元格构建的UITableView,细节场景是具有固定数量的节和单元格的静态UITableView。

我想在我的应用程序中实现Dynamic Type和Self-Sizing Cells,以便用户可以更改基本字体大小。 到目前为止,我已成功使用原型单元的滚动列表制作自调整单元格:通过使用自动布局,将每个标签中的行数设置为0,并设置tableView.rowHeight = UITableViewAutomaticDimension ,每个原型单元格的高度增长或缩小以适应其中的文本大小。

但我无法在静态表视图中实现相同的效果。 无论我使用自定义单元格还是内置单元格类型,字体都会增大/缩小,但单元格高度则不会。

所以我的问题实际上是两个问题:1)是否可以在静态表视图中实现自调整单元格,就像我对原型表视图一样? 2)如果第一个问题的答案为否,我如何编写测量静态表格视图单元格中标签高度的代码并适当调整单元格高度?

谢谢!

静态表视图返回Interface Builder中设置的行高。 tableView.rowHeight设置似乎完全被忽略。 这显然是UIKit中的一个错误。

为了解决这个问题,只需覆盖-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath并返回UITableViewAutomaticDimension

首先在你的class级中添加这两个function

 func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } 

其次,为了使UITableViewAutomaticDimension工作,请确保已添加相对于单元容器视图的所有左,右,底部和顶部约束。 另外不要忘记将标签的行数设置为零。

由于这是一个静态表,你不能将单元格出列,因此你必须为它们创建IBOutlets,我将它们保存在这样的数组中:

 @IBOutlet var cells: [UITableViewCell]! 

然后你将不得不实现heightForRowAtIndexPath并计算大小:

 var rowSizes: [Int: CGFloat] = [:] override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return calculateHeightForCell(indexPath) } func calculateHeightForCell(indexPath: NSIndexPath) -> CGFloat { // check if we already calculated the height if let height = rowSizes[indexPath.row] { return height } // else, calculate it let cell = cells[indexPath.row] let size = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize) rowSizes[indexPath.row] = size.height return size.height } 

rowSizes就像一个缓存,它将保持行高,因此它们只会被计算一次。 更改字体大小时,只需清空rowSizes并刷新表格,以便再次计算它们。

我很感谢昨天发布的问题的答案。 不幸的是(可能是因为我自己作为iOS程序员缺乏经验)我无法使systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)方法工作。 然而,经过一些试验和错误,我发现了一种似乎有效的不同方法:

 import UIKit class MasterTVC: UITableViewController { @IBOutlet weak var staticCustomCellLabel: UILabel! //viewDidLoad override func viewDidLoad() { super.viewDidLoad() self.tableView.estimatedRowHeight = 44.0 staticCustomCellLabel.text = "This is the text for the static custom cell label; This is the text for the static custom cell label; This is the text for the static custom cell label" //Register handleDynamicTypeChange in observer: self NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleDynamicTypeChange:", name: UIContentSizeCategoryDidChangeNotification, object: nil) } //deinit deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } //handleDynamicTypeChange //called when user changes text size in Settings > General > Accessibility > Larger Text //or Settings > Display & Brightness > Text Size func handleDynamicTypeChange(notification: NSNotification) { staticCustomCellLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody) self.tableView.reloadData() } //tableView:heightForRowAtIndexPath override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } } 

在Storyboard方面,设置从一个具有以下属性的Table View Controller开始:

  • 课程:MasterTVC(我的定制课程);
  • 指定初始视图控制器;
  • 内容:静电电池;
  • 风格:分组
  • 章节:1。

第1:

  • 行:1。

表视图单元格:

  • 样式:自定义(使用“基本”在此处导致标签在“设置”中更改文本大小时消失);
  • 含有UILabel。

UILabel进一步配置为:

  • 字体:Body(动态类型);
  • 线条:0;
  • 在内容视图的顶部,底部,左侧和右侧边缘的所有四个边上固定(我使用了相应的约束8,8,15,15);
  • 在自定义类代码中使用@IBOutlet。

这对我来说在Xcode 7中设计了iOS 9,在启用了Auto Layout的情况下设计了Swift 2。 有趣的是,如果你去除用于立即响应文本大小变化的NSNotificationCenter代码,自调整单元格代码基本上是两行:在viewDidLoad中设置estimatedRowHeight,并从tableView:heightForRowAtIndexPath返回UITableViewAutomaticDimension。

基于这些结果,我相信我原来问题的答案是:1)是; 2)见1。