繁体   English   中英

iOS TableView 重新加载并滚动到顶部

[英]iOS TableView reload and scroll top

第二天我无法解决表的问题。

我们有一个 segmentedControl,它在更改时会更改表格。 假设控件的段中有 3 个元素,相应地有 3 个 arrays(这很重要,它们的大小不同)我需要在更改 segmentedControl 时向上滚动表。

看起来一切都很简单:contentOffset =.zero 和 reloadData ()

但。 这不起作用,我不知道为什么表格不向上滚动。

唯一有效的是:

UIView.animate (withDuration: 0.1, animations: {
            self.tableView.contentOffset = .zero
        }) {(_) in
            self.tableView.reloadData ()
}

但是现在表上去还有一个问题,可能会出现bug,因为segmentedControl变了,而另一个数组里面的数据可能不是,我们还没有做reloadData()

也许我无法理解显而易见的事情))祝贺即将到来的假期!

UItableView方法scrollToRow(at:at:animated:)滚动表格视图,直到由索引路径标识的行位于屏幕上的特定位置。

使用

tableView.scroll(to: .top, animated: true)

你可以使用我的扩展

extension UITableView {

    public func reloadData(_ completion: @escaping ()->()) {
        UIView.animate(withDuration: 0, animations: {
            self.reloadData()
        }, completion:{ _ in
            completion()
        })
    }

    func scroll(to: scrollsTo, animated: Bool) {
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
            let numberOfSections = self.numberOfSections
            let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
            switch to{
            case .top:
                if numberOfRows > 0 {
                     let indexPath = IndexPath(row: 0, section: 0)
                     self.scrollToRow(at: indexPath, at: .top, animated: animated)
                }
                break
            case .bottom:
                if numberOfRows > 0 {
                    let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
                    self.scrollToRow(at: indexPath, at: .bottom, animated: animated)
                }
                break
            }
        }
    }

    enum scrollsTo {
        case top,bottom
    }
}

在调用 reloadData 后尝试直接滚动到顶部后,我收到以下错误

[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (0) beyond bounds (0) for section (0).'

这为我修复了它:

    tableView.reloadData()
    if tableView.numberOfRows(inSection: 0) != 0 {
        tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
    }

我找到了更好的方法来做到这一点。 它就像一个魅力。

let topIndex = IndexPath(row: 0, section: 0)
tableView.scrollToRow(at: topIndex, at: .top, animated: true)

好的。 所以人们发现将 tableview 滚动到顶部的问题

self.tableView.setContentOffset(.zero, animated: false)

并且需要做不必要的重新加载数据来解决这个问题!

那么setContentOffset有什么问题是 iOS 的一种错误?
最小和最简单的答案是否定的那么问题是什么?

答案是动态行正在使用UITableView.automaticDimension Tableview 使用行高以及数据源中的数量或部分和行来计算其内容偏移量。 所以在动态高度没有正确执行 scrollToTop 的情况下,这是因为它需要重新计算每个行高和内容大小。

所以为了从 tableview 中减少这个包,我们可以提供一个估计的行高,比如

self.tableView.estimatedRowHeight = 117 // whatever your value 

希望这会帮助某人:)

通过两次重新加载,完美地在重新加载时到达页面顶部

没有令人不安的动画

dataForSource = nil
tableView.reloadData()

DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
    self.dataForSource = realData
    self.tableView.reloadData()
}

你可以用这个。

    tableView.setContentOffset(CGPoint.zero, animated: true)

您可以将动画设置为您的要求

Swift 5.1 *,尝试了一行代码并为我工作:

tableView?.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

将此代码添加到我的 tableview 以对齐内容以从顶部开始。

希望会有所帮助。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM