web-dev-qa-db-ja.com

iOS TableViewのリロードとスクロールトップ

二日目、私はテーブルの問題を解決できません。

変更すると、テーブルを変更するsegmentedControlがあります。コントロールのセグメントに3つの要素があり、それに応じて3つの配列(サイズが異なることが重要です)があり、segmentedControlが変更されたときにテーブルを上にスクロールする必要があるとします。

そして、すべてがシンプルなようです:contentOffset = .zero and reloadData()

だが。これは機能しません。なぜテーブルが上にスクロールしないのかわかりません。

働いた唯一のもの:

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

しかし、テーブルが上がると、もう1つの問題が発生し、バグが発生する可能性があります。これは、segmentedControlが変更され、他の配列のデータが変更されていない可能性があるためです。

たぶん私は明らかなことを理解することはできません))今後の祝日おめでとうございます!

9
Mikhail Sein

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
    }
}
17
AshvinGudaliya

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)
    }
4
rbaldwin

これを行うより良い方法を見つけました。それは魅力のように機能します。

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

これを使用できます。

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

必要に応じてアニメーションを設定できます

1
Baltej Singh

はい。だから人々はテーブルビューを上にスクロールすることで問題を見つける

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

そして、これを修正するために不必要にデータをリロードする必要があります!

では、setContentOffsetの問題はiOSのバグのようなものですか?
最小かつ最も簡単な答えは[〜#〜] no [〜#〜]ですから、問題は何ですか?

答えは、動的行UITableView.automaticDimensionを使用していることです。 Tableviewは、行の高さ、およびデータソースにあるセクションまたは行の数でコンテンツオフセットを計算します。したがって、動的な高さがscrollToTopを正しく実行しない場合、すべての行の高さとコンテンツサイズを再計算する必要があるためです。

したがって、tableviewからこのバンドルを減らすために、次のような推定行の高さを提供できます。

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

うまくいけば、これは誰かを助けるでしょう:)

1