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

leo*_*loo 20 uitableview ios swift

我有一个UITableView与动态大小的单元格.这意味着我已经设置:

tableView.estimatedRowHeight = 50.0
tableView.rowHeight = UITableViewAutomaticDimension
Run Code Online (Sandbox Code Playgroud)

现在我想获得整个表格视图的高度.我尝试了它,tableView.contentSize.height但只返回估计的行高,而不是表视图的实际动态高度.

如何获得整个表格视图的动态高度?

leo*_*loo 21

我终于破解了一个解决方案:

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)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 调用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
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 这种东西是如此的hacky它让我焦虑.什么是苹果在做什么? (5认同)
  • 这对我有用,但我不得不将我的代码放在`viewDidLayoutSubviews()`中,因为在`viewDidLoad()`中,单元格尚未加载. (2认同)

Shu*_*ngh 14

上面提到的解决方案都很好。我尝试了一种不同的方法,它流畅且易于理解。只需复制粘贴代码即可工作。

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
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 一般来说,最后一个答案从来都不是我的首选答案,但这个答案节省了我两天的工作时间。在应用程序上线之前,我几乎要重做整个屏幕。谢了哥们 (3认同)