【问题标题】:How to allow an off screen UITableViewCell push down content offset?如何允许屏幕外 UITableViewCell 下推内容偏移?
【发布时间】:2019-06-12 07:00:18
【问题描述】:

我有一个 UITableView,其中包含一堆单元格。

如果用户单击第二个单元格,则第一个单元格应设置动画并显着扩展其高度,并将所有其他单元格向下推,使用户的滚动位置保持在同一位置。当两个单元格都在屏幕上时,我的代码 100% 正确工作。 UITableView的contentSize显着增长,contentOffset没有变化。

但是,如果用户向下滚动,只有第二个单元格可见,当他们点击它时,第一个单元格会展开到屏幕外,用户什么也不会发生。

UITableView 的 contentSize 不变,contentOffset 也不变。一旦用户稍微向上滚动并看到展开单元格的底部,contentSize 和 contentOffset 就会更新以反映第一个单元格确实要大得多的事实(但从用户的角度来看没有任何变化)

在展开前后对单元格的索引路径调用heightForRowAtIndexPath会返回预期值。

我的代码有很多事情要做,但应该是动画扩展的主要部分在这里:

UIView animateWithDuration:0.3
 animations:^{
   performSelectorOnMainThread(@selector(updateItemHeights:), withObject: nil, waitUntilDone: YES)
 }
 completion:^(BOOL finished){}]

以及updateItemHeights的实现:

   beginUpdates
   endUpdates
   self.contentSize = sizeThatFits([contentSize.width, CGFLOAT_MAX])

iOS 似乎试图通过允许上方的单元格展开来将用户保持在当前上下文中。

如何让屏幕外单元格将其他单元格向下推?

【问题讨论】:

    标签: ios iphone uitableview


    【解决方案1】:

    感谢表格视图出队系统,当一个单元格不可见时,它不会被加载。因此,如果表格视图在屏幕上不可见,则表格视图不会对更改进行动画处理。

    我在这里看到 2 个选项:

    在更新高度之前滚动到动画单元格

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let animatedIndexPath = ...
        let visibleRows = tableView.indexPathsForVisibleRows ?? []
        if visibleRows.contains(animatedIndexPath) {
            self.tableView.reloadRows(at: [animatedIndexPath], with: .automatic)
        } else {
            UIView.animate(withDuration: 0.3, animations: {
                self.tableView.scrollToRow(at: animatedIndexPath, at: .none, animated: false)
            }) { _ in
                self.tableView.reloadRows(at: [animatedIndexPath], with: .automatic)
            }
        }
    }
    

    更新单元格后调整内容偏移量

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let animatedIndexPath = ...
        let visibleRows = tableView.indexPathsForVisibleRows ?? []
        if visibleRows.contains(animatedIndexPath) {
            self.tableView.reloadRows(at: [animatedIndexPath], with: .automatic)
        } else {
            let offset = tableView.contentOffset
            tableView.reloadData()
            tableView.layoutIfNeeded() // forces the new offset computation
            tableView.setContentOffset(offset, animated: true)
        }
    }
    

    (您可能会因为表格视图动态高度计算而遇到一些问题,请禁用它tableView.estimatedRowHeight = 0

    【讨论】:

      猜你喜欢
      • 2019-03-10
      • 2018-05-16
      • 2013-01-05
      • 2023-02-21
      • 1970-01-01
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      • 2012-06-11
      相关资源
      最近更新 更多