ios 如何在单元格动态调整大小时获取UITableView的高度?

3bygqnnd  于 2023-05-02  发布在  iOS
关注(0)|答案(9)|浏览(333)

我有一个UITableView,其中的单元格是动态大小的。这意味着我设置了:

tableView.estimatedRowHeight = 50.0
tableView.rowHeight = UITableViewAutomaticDimension

现在我想得到整个表视图的高度。我尝试通过tableView.contentSize.height获取它,但这只返回估计的行高,而不是表视图的实际动态高度。
如何获得整个表视图的动态高度?

ltskdhd1

ltskdhd11#

最后,我想出了一个解决方案:
tableView.contentSize.height不适用于动态单元格,因为它们只返回单元格的数量 * estimatedRowHeight
因此,要获得动态表视图高度,您需要查找所有可见的单元格,并将它们的高度相加。请注意,这只适用于比屏幕短的表视图。
然而,在我们执行上述操作以查找可见单元格之前,重要的是要知道注意我们需要在屏幕上获得表视图,以便我们可以获得可见单元格。要做到这一点,我们可以为表视图设置一个高度限制,使其显示在屏幕上:
1.设置表视图约束的高度:

// Class variable heightOfTableViewConstraint set to 1000
heightOfTableViewConstraint = NSLayoutConstraint(item: self.tableView, attribute: .height, relatedBy: .equal, toItem: containerView, attribute: .height, multiplier: 0.0, constant: 1000)
containerView.addConstraint(heightOfTableViewConstraint)

1.调用tableView。layoutIfNeeded(),完成后,查找可见的单元格,总结它们的高度,并编辑heightOfTableViewConstraint

UIView.animate(withDuration: 0, animations: {
    self.tableView.layoutIfNeeded()
    }) { (complete) in
        var heightOfTableView: CGFloat = 0.0
        // Get visible cells and sum up their heights
        let cells = self.tableView.visibleCells
        for cell in cells {
            heightOfTableView += cell.frame.height
        }
        // Edit heightOfTableViewConstraint's constant to update height of table view
        self.heightOfTableViewConstraint.constant = heightOfTableView
}
r9f1avp5

r9f1avp52#

上面提到的解决方案都很好。我尝试了一种不同的方法&它流畅而清晰地理解。只需复制粘贴代码&它将工作。

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    tableView.removeObserver(self, forKeyPath: "contentSize")
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "contentSize"{
            if object is UITableView{
                if let newValue = change?[.newKey]{
                    let newSize = newValue as! CGSize
                    heightOfTableViewConstraint.constant = newSize.height
                }
            }
        }
    }
g6ll5ycj

g6ll5ycj3#

这个问题已经有答案了,但我也想分享一下我的经验。
我也有同样的问题。我已经搜索了许多类似的问题的答案,并尝试了他们的答案,不工作.
终于找到leonardloo answer了谢谢你,但这并没有解决我的问题。我只想完成他的回答。我把这个代码从他的回答:

UIView.animate(withDuration: 0, animations: {
self.tableView.layoutIfNeeded()
}) { (complete) in
    var heightOfTableView: CGFloat = 0.0
    // Get visible cells and sum up their heights
    let cells = self.tableView.visibleCells
    for cell in cells {
        heightOfTableView += cell.frame.height
    }
    // Edit heightOfTableViewConstraint's constant to update height of table view
    self.heightOfTableViewConstraint.constant = heightOfTableView
}

在这个代码块中:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    ...
    if indexPath.row == data.count-1{ 
        // Insert the code here
    }
    return cell
}

这意味着在table中的所有行都被加载之后,我们使用这段代码更新行的高度。它的工作!!!

mkshixfv

mkshixfv4#

尽管@leonardloo的答案部分正确,而且可能适合许多人的需求,但我想分享我是如何解决这个问题的。
我有一个大的tableView与大行,并有同样的问题。当我应用@leonardloo的答案时,我发现它只绘制了它在开始时找到的可见单元格的数量,它绘制了1行,而它应该绘制5行(我的数据源计数)。
为了解决这个问题,我找到了一个简单的方法:

UIView.animate(withDuration: 0, animations: {
self.tableView.layoutIfNeeded()
}) { (complete) in
    var heightOfTableView: CGFloat = 0.0
    // Get visible cells and sum up their heights
    let cells = self.tableView.visibleCells
    for cell in cells {
        heightOfTableView += cell.frame.height
    }
    // Edit heightOfTableViewConstraint's constant to update height of table view
    // Set tableView's constraint to height + 1 so that 
    // it can still draw the next visible cell it's supposed to.
    self.heightOfTableViewConstraint.constant = heightOfTableView + 1
}

这里的要点是让它绘制下一个单元格,以便通过将constraint常量设置为height + 1,它也会被计入visibleCells中。我已经测试过了,它现在看起来像一个魅力。

uelo1irk

uelo1irk5#

当你有页眉、页脚、节头之类的东西时,上面的答案不起作用。只使用可见单元格的高度是一个灾难。相反,您可以使用tableView contentSize height。

UIView.animate(withDuration: 0, animations: {
        self.tableView.layoutIfNeeded()
        }) { (complete) in
            self. heightOfTableViewConstraint.constant = self.tableView.contentSize.height
    }
kuhbmx9i

kuhbmx9i6#

您应该在下面的delegate方法中计算tableView的高度,

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

    //Get the height required for the TableView to show all cells
    if indexPath.row() == (tableView.indexPathsForVisibleRows.last! as! NSIndexPath).row {
        //End of loading all Visible cells
        float heightRequiredForTable = tableView.contentSize.height

        //If cell's are more than 10 or so that it could not fit on the tableView's visible area then you have to go for other way to check for last cell loaded 
    }
}
ukqbszuj

ukqbszuj7#

只需维护一个类型为CGFLoat的数组,并将UITableViewAutomaticDimension追加到tableviewcellForRowAtindexPath委托中

var cellHeight = [CGFloat]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cellHeight.append(UITableViewAutomaticDimension)
}
ssgvzors

ssgvzors8#

我将在这里添加我的答案,因为我有点挣扎。
我的表格视图使用了有标题的部分,所以仅仅获取可见单元格的高度是不起作用的。我最后做的是首先为tableView设置一个超大的高度,这样内容就都会被添加进去。然后在tableView的最后一个cell上,我将tableView的大小调整为与content相同的高度。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  ... // do your normal cell processing

  // determine height and change it
  if indexPath.section == (self.sectionTitles.count - 1) && indexPath.row == (sectionData.count - 1) {

    UIView.animate(withDuration: 0, animations: {
      self.tableView.layoutIfNeeded()
    }) { complete in

      // Edit heightOfTableViewConstraint's constant to update height of table view
      self.tableViewHeightConstraint.constant = self.tableView.contentSize.height
    }
  }
}
u7up0aaq

u7up0aaq9#

你可以试试这个代码

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

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

相关问题