在UiTableView的删除行动画中观察当前的contentOffset

Observe current contentOffset during UiTableView's delete rows animation

我根据 table 视图的内容偏移量设置了 UI 行为。除了一种情况外,它在所有情况下都能正常流畅地工作:当 tableView 开始删除带有动画的行时。

问题出现在删除前内容很多,用户滚动了一部分,删除后tableView可以不滚动显示全部内容。在那种情况下 table 视图在删除动画的同时平滑地更改内容偏移量。

导致我出现问题的主要原因是在删除动画期间未调用 scrollView 委托的方法 scrollViewDidScroll,我的行为不起作用。

我尝试使用 KVO 观察偏移变化:

observation = tableView.observe(\.contentOffset, options: [.new, .old]) { (_, change) in
    print(change)
}

它工作得更好,但在第一时刻只触发一次最终值,所以我没有收到任何中间值,我需要这些值才能使 UI 反应平稳。

好的,我尝试使用 UIView.animate 和兄弟姐妹来激活我的行为。但是发现很难选择参数来同步我的动画和table视图的偏移动画。

那么,我错过了什么?是否可以在行删除动画期间观察到任何中间偏移值?

好的,伙计!我有一个好消息要告诉你 =] 你可以使用层表示树来观察每个时刻的 UI 值。

  1. 将 tableView 更新包装到 CATransaction 中
    let displayLink = CADisplayLink(target: self, selector: #selector(adjustHeader))
    displayLink.add(to: .current, forMode: .common)

    CATransaction.begin()
    CATransaction.setCompletionBlock(displayLink.invalidate)
    // do tableView updates here
    CATransaction.commit()

  1. 使用图层表示树计算当前偏移量。例如:
@objc private func adjustHeader() {
    guard
        let headerPresentationLayer = headerView.layer.presentation(),
        let viewPresentationLayer = view.layer.presentation(),
        let tableViewPresentationLayer = tableView.layer.presentation()
        else { return }

    let origin = tableViewPresentationLayer.convert(headerPresentationLayer.frame.origin, to: viewPresentationLayer)
    print("LayerPresentationTree: \(origin)")
    offsetDepandableView.frame.origin = origin
}