3

UIViewController保持する がありNSFetchedResultsControllerます。一番上に行を挿入した後、挿入前と同じように行を表示したままにします。これは、更新直後に contentOffSetY を維持するために計算を行う必要があることを意味します。計算は正しいのですがscrollViewDidScroll、指定した contentOffsetY までスクロールした後に が呼び出されることに気付きました。これにより、破損した状態になります。これはロギングです:

Will apply an corrected Y value of: 207.27359771728516
Scrolled to: 207.5
Corrected to: 207.27359771728516
Scrolled to: 79.5 <-- Why is this logline here?

サンプル プロジェクトを直接複製できます: https://github.com/Jasperav/FetchResultControllerGlitch (コミットhttps://github.com/Jasperav/FetchResultControllerGlitch/commit/d46054040139afeeb648e1e0b5b113bd98685b4aプロジェクトの最新バージョンはグリッチのみで、奇妙な呼び出しscrollViewDidScroll メソッドはなくなりました. グリッチを修正したら賞金を授与します. 最新バージョンを複製して実行し、少しスクロールしてください. 奇妙なコンテンツ オフセット (グリッチ) が表示されます. プロジェクトを実行すると、奇妙な出力が表示されます。これはcontrollerDidChangeContent方法です:

public func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    let currentSize = tableView.contentSize.height

    UIView.performWithoutAnimation {
        tableView.endUpdates()

        let newSize = tableView.contentSize.height
        let correctedY = tableView.contentOffset.y + newSize - currentSize

        print("Will apply an corrected Y value of: \(correctedY)")
        tableView.setContentOffset(CGPoint(x: 0,
                                           y: correctedY),
                                   animated: false)
        print("Corrected to: \(correctedY)")
    }
}

tableView.layoutIfNeededの直後に呼び出すとtableView.endUpdates()、デリゲートは既に呼び出されています。デリゲート メソッドを呼び出す原因は何ですか? スクロールしない方法はありますか?

4

1 に答える 1