sizeToFit() 返回错误的高度 - 需要在 heightForRow 中查找单元格宽度

Posted

技术标签:

【中文标题】sizeToFit() 返回错误的高度 - 需要在 heightForRow 中查找单元格宽度【英文标题】:sizeToFit() returns wrong height - Need to find cell width in heightForRow 【发布时间】:2016-01-11 21:46:02 【问题描述】:

我正在尝试根据内容制作具有动态单元格高度的 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 在我的故事板和代码中是相同的。

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


编辑:约束:

【问题讨论】:

我可以建议自动布局吗?它为您完成所有工作。见***.com/questions/31658526/… @SwiftArchitect 我尝试了您在该线程中描述的解决方案,但自动布局似乎无法正确调整单元格高度。我将我的约束添加到我对帖子的最新编辑中,如果你能看一下并告诉我我做错了什么,我将不胜感激。 我得到了一个临时解决方案,它使用一个幻数来获取表格视图宽度的内容偏移量 (8)。糟糕的解决方案,但它现在有效。仍在寻找正确的答案。 您是否使用或缺少“相对于边距”?您使用的是XIB 还是storyboard 我正在使用故事板,我猜是的。如何做到这一点 【参考方案1】:

自动标注

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

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

(*) 2 行 代码,准确地说。 通过比较 2 lines solution 和 multiple methods override solution 来说服自己。


边距说明

XIB & storyboard:您可以控制约束及其与边距的关系。 请注意,当使用 相对于边距 时,项目顺序很重要,因为边距通常是插图。 有关详细信息,请参阅https://***.com/a/25420909/218152。

storyboard:您可以访问来自 IB 的附加 topLayoutGuidebottomLayoutGuide 属性,这可能对您的视图控制器有价值,但对于你的UITableViewCell

【讨论】:

以上是关于sizeToFit() 返回错误的高度 - 需要在 heightForRow 中查找单元格宽度的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式在 UILabel 上设置 sizeToFit 宽度和高度?

UILabel 中 sizeToFit 的高度不正确

调用 sizeToFit 时,UIButton 无法使用自定义字体正确调整高度

iOS UITextView sizeToFit 使 iPad 中内容文本的高度加倍

有没有办法可靠地计算 UITextView 的高度?

在 iOS 中,带有属性文本的 textview 的高度有时是错误的