This question already has answers here:
reloadData() of UITableView with Dynamic cell heights causes jumpy scrolling

(20个答案)


2年前关闭。




问题:当我在UITableView底部(且仅在底部)并且tableView.beginUpdates()/tableView.endUpdates()被调用时,UITableView跳了一点。我不希望它这样做。

设置:我有一个UITableViewUITableViewCells,它们的大小都是不同的,并且我使用UITableViewAutomaticDimension来设置单元格的大小。

示例:
当我位于UITableView的底部并选择一个单元格,该单元格随后调用tableView.beginUpdates()/tableView.endUpdates()时,UITableView会向上滚动/跳转一点。

有没有人找到一种方法来做到这一点,因此在tableView.beginUpdates()的末尾调用tableView.endUpdates()/UITableView后不会出现跳动?

暂时我正在手动计算我的所有UITableViewCells,但我不想这样做,因为我想利用UITableViewAutomaticDimension

代码:

这是一些代码,显示tableView.beginUpdates()/tableView.endUpdates()之间的情况:
    tableView.beginUpdates()
    cell!.setNeedsUpdateConstraints()
    cell!.updateConstraintsIfNeeded()
    cell!.setNeedsLayout()
    cell!.layoutIfNeeded()
    tableView.endUpdates()

我的看法将出现:
public override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    self.tableView.estimatedRowHeight = 150.0
    self.tableView.rowHeight = UITableViewAutomaticDimension


    self.tableView.reloadData()
    //Bug in 8.0+ forces us to call three extra methods to get dynamic cell heights to work correctly...
    self.tableView.setNeedsLayout()
    self.tableView.layoutIfNeeded()
    self.tableView.reloadData()
}

我的heightForRow:
public override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    return UITableViewAutomaticDimension

}

更新:从cell!.setNeedsUpdateConstraints()/cell!.updateConstraintsIfNeeded()中删除cell!.setNeedsLayout()cell!.layoutIfNeeded(tableView.beginUpdates()tableView.endUpdates()似乎停止了跳跃,但是随后我的单元格没有调整大小...

编辑:仅当在UITableView底部时才发生。

最佳答案

实际上,我找到了解决此问题的好方法。.这让我发疯了,但请看:

那么你

  • 有一个包含可扩展内容的表
  • 要设置单元约束的动画(例如,高度)
  • 因此,您调用tableView.beginUpdates()和tableView.endUpdates()

  • 桌子也跳了起来..

    正如其他人之前所说,这是因为更新tableView使tableView滚动

    解决方案?

    假设您的代码如下所示:
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            let cell = tableView.cellForRow(at: indexPath)
            cell.heightConstraint = 100
            UIView.animate(withDuration: 0.15, animations: {
    
                self.view.layoutIfNeeded()
                self.tableView.beginUpdates()
                self.tableView.endUpdates()
            }, completion: nil)
    }
    

    然后,要解决跳转问题,您必须保存当前的tableView滚动位置,直到调用tableView.endUpdates()为止。

    像这样:
    var currentScrollPos : CGFloat?
    
    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
            // Force the tableView to stay at scroll position until animation completes
            if (currentScrollPos != nil){
                tableView.setContentOffset(CGPoint(x: 0, y: currentScrollPos!), animated: false)
            }
    }
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            let cell = tableView.cellForRow(at: indexPath)
            cell.heightConstraint = 100
            UIView.animate(withDuration: 0.15, animations: {
    
                self.currentScrollPos = self.tableView.contentOffset.y
    
                self.view.layoutIfNeeded()
                self.tableView.beginUpdates()
                self.tableView.endUpdates()
    
                self.currentScrollPos = nil
            }, completion: nil)
    }
    

    关于ios - 使用UITableViewAutomaticDimension时,在开始/结束更新后,UITableView会跳转,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33789807/

    10-10 21:07