sizeToFit() returns 高度错误 - 需要在 heightForRow 中找到单元格宽度

sizeToFit() returns wrong height - Need to find cell width in heightForRow

我正在尝试根据内容制作具有动态单元格高度的 UITableView。我的应用程序是一个文章查看器。我尝试用这些函数计算单元格的高度。

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
    let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
    label.numberOfLines = 0
    label.lineBreakMode = .ByTruncatingTail
    label.font = font
    label.text = text

    label.sizeToFit()
    return label.frame.height
}

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    let post = FeedController.sharedController.allPosts[indexPath.row]
    var height = 16.0
    if post.hasImage {
        height += Double(self.view.frame.width) / (4/3)
    }

    let titleH = heightForView(post.title!, font: UIFont(name: "LiberationSerif-Bold", size: 20.0)!, width: self.tableView.bounds.width)
    let descH = heightForView(post.desc!, font: UIFont(name: "LiberationSerif", size: 17.0)!, width: self.tableView.bounds.width)

    let totalHeight = CGFloat(height+Double(titleH)+Double(descH))

    print("imageH: \(height), titleH: \(titleH) detailH: \(descH) totalH:\(totalHeight)")
    return totalHeight
}

当我运行它时,它看起来像这样,如您所见,底部标签被切掉了。

我运行它通过接口断点,在那里你可以看到错误的原因:

呈现的尺寸比 sizeToFit() 的估计尺寸大一个尺寸,正如您从我的日志语句中看到的那样:

imageH: 297.25, titleH: 44.5 detailH: 56.5 totalH:398.25

我怀疑这个计算错误的原因是我为 heightForView 函数提供了错误的宽度参数。我尝试过使用 tableView.contentSize 和许多其他东西。 lineBreakMode 在我的故事板和我的代码中是相同的。

我想我需要的是一种更好的方法来找到单元格的预期宽度,或者任何其他可以给我正确预期高度的解决方案。


编辑:约束:

自动维度

使用更少的代码(*),您可以完全放弃 heightForRowAtIndexPath,并使用 autolayout 处理所有内容。

  1. 不要覆盖 heightForRowAtIndexPath(所有代码都会消失)
  2. 告诉 table 视图去做艰苦的工作(例如 viewDidLoad):
    self.tableView.estimatedRowHeight = 88
    self.tableView.rowHeight = UITableViewAutomaticDimension

(*) 2 行 代码,准确地说。 通过比较 2 lines solution against multiple methods override solution.

说服自己

保证金注释

  • XIB & storyboard:您有能力控制约束及其与保证金的关系。
    请注意,当使用 Relative to margin 时,项目顺序很重要,因为边距通常是内嵌的。 有关详细信息,请参阅 。

  • storyboard:您可以从 IB 访问额外的 topLayoutGuidebottomLayoutGuide 属性,这可能是对您的视图控制器有价值,但对您的 UITableViewCell.

  • 是 off-topic