簡體   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