如何计算 tableView 行高并将值传递给 heightForRowAtIndexPath

Posted

技术标签:

【中文标题】如何计算 tableView 行高并将值传递给 heightForRowAtIndexPath【英文标题】:How to calculate tableView row height and pass value to heightForRowAtIndexPath 【发布时间】:2016-04-21 23:11:17 【问题描述】:

我有一个带有自定义单元格的 tableView。 每个单元格都有不同的界面、元素。它们都有不同的尺寸。 每个单元格都有不同类型的元素及其数量。 所有这些元素都是动态创建的,所以我正在创建它们,制作它们的框架并添加为子视图

所以 heightForRowAtIndexPathcellForRowAtIndexPath 之前执行的问题,我在其中创建行并构造其界面,但我不知道如何将计算出的高度传递给 heightForRowAtIndexPath

如何计算行高之前并将其值传递给 heightForRowIndexPath 以正确绘制我的 tableView?

【问题讨论】:

所以你知道每个单元格的视图框架是什么,但不知道单元格的高度是多少? 我不知道如何将计算出的高度传递给 heightForRowAtIndexPath,据我所知,它只能改变行高 【参考方案1】:
    尝试创建UITableViewCell 的子类。 您创建的所有元素都放在UIView 中,然后放在一个单元格中。 创建三个NSLayoutConstraint,一个从UIView.top 到单元格顶部,第二个从UIView.bottom 到单元格底部,第三个-UIView 的高度。 在tableViewControllerviewDidLoad方法中设置行高为UITableViewAutomaticDimension

override func viewDidLoad() 
   super.viewDidLoad()
   self.tableView.rowHeight = UITableViewAutomaticDimension

    在 UITableViewCell 的子类中创建一个方法来计算单元格的高度并更改设置单元格高度的 NSLayoutConstraint。例如:

func adjustHeightOfInnerView() 
   let height = 100
   self.myInnerCellViewHeightConstraint.constant = height
   self.contentView.setNeedsUpdateConstraints()

    cellForRowAtIndexPath方法中调用adjustHeightOfTableview

func tableView (tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
   let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! myTableViewCellSubclass
   cell.adjustHeightOfTableview()
   return cell

【讨论】:

非常感谢您。我晚上在家里试试 你能帮我完成第三步吗? 问题是我不知道如何正确地做到这一点。我尝试了这样的方法 let top = NSLayoutConstraint(item: cell.contentView, attribute: .Top, relatedBy: .Equal, toItem: btn, attribute: .Top, multiplier: 1, constant: 10) 但没有任何改变 您在创建约束后调用了contentView.setNeedsUpdateConstraints() 在 Interface Builder 中创建 UIView 和约束。在 CustomTableViewCell 中的 heightConstraint 上创建一个 IBOutlet 并以编程方式更改其值。【参考方案2】:

如果您的单元格视图非常复杂,并且每个组件的高度都取决于数据源。您可以尝试在heightForRowIndexPath 方法中创建视图,然后将创建的视图缓存到视图控制器中的字典并直接在cellForRowAtIndexPath 中使用。这样,您只需在用户滚动表格时创建一次视图。如果数据源的变化不是很频繁,您也可以重用 heightForRowIndexPath 中的缓存视图。

如果 tableview 有很多行,你应该在estimatedHeightForRowAtIndexPath 中返回一个近似的高度值,以加快视图控制器的加载过程。否则在加载tableview时,它会尝试计算所有行的高度,这可能需要很多时间。

但我真的不认为你的细胞会这么复杂。如果只有一些 UITextLabels 的高度依赖于数据源,您可以简单地计算标签的高度,然后将其添加到其他组件的高度,这是固定的。

【讨论】:

关于它的复杂性 - 它是。它的社交网络和当我将与用户发布的墙一起发布时——他们都可以包含文本、图片(最多 10 个)、音频、视频、文档和其他附件。它也可以是重新发布,因此所有内容都会稍微移动一点,上面将是发布者的名称。所以没有办法在它的 uitableviewcell.swift-file 中计算行高,然后传递给原来的 heightForRowAtIndexPath,是吗? @HrenoHrenovich 不,你可以仔细检查设计并提取一些图案。例如,对于图像、音频、视频或文档,每个单项的高度通常是固定的,您可以通过 numberOfTheItem*eachItemHeight 获得总高度。 就是这样。所以问题是关于将计算高度正确设置为 rowHeight。 @HrenoHrenovich 你可以先试试我的解决方案,因为你已经有了创建视图的代码,应该很快。如果它工作正常,你的问题就解决了。但如果您有性能问题,那么我们需要寻找其他解决方案。 哦,好的。我会尽力。谢谢你【参考方案3】:

你真的应该考虑继承 UITableViewCell 并在你的子类中添加你的自定义逻辑。

从那里开始,你会有这样的选择:

    在您的单元格中创建静态方法,该方法将接收绘制单元格所需的所有数据(例如 heithtForCellWithFirstString:secondString:accessoryImage 等)并使用字符串大小计算方法计算高度。在 heightForRowAtIndexPath 中使用此方法。

    使用自动布局来布置单元格的子视图,然后将表格视图的行高属性设置为 UITableViewAutomaticDimension。这样,您根本不需要 heightForRow 委托方法。有很多这方面的教程,例如:http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift

【讨论】:

谢谢。但是,如果我在 heightForRowAtIndexPath 和单元格中分别计算高度 - in 将执行两次相同的操作。关于自动布局 - 我考虑过这一点,但元素一直都有不同的位置,也可能没有一个元素,所以连接到行顶部或底部将毫无意义。这就是为什么我需要任何关于在我的案例中实施一些逻辑决策的建议 在 cellForRow 之前计算高度是另一个操作 - 因为它不涉及视图创建。这只是 string.sizeWithAttributes 和您的自定义边距算术

以上是关于如何计算 tableView 行高并将值传递给 heightForRowAtIndexPath的主要内容,如果未能解决你的问题,请参考以下文章

如何在一页上选择产品数量并将值传递给 cart.php

Swift iOS - 如何将直接从 TableViewCell 的子类中获取的值传递给 TableView 的 didSelectRow?

ios 关于tableview方法执行顺序为啥会先走判断行高

tableView计算动态行高的总结

如何获取当前视图HTML源并将其作为String传递给JSF ManagedBean

TSQL - 计算多语句表 UDF 中的特定值并将它们传递给附加列