21

セルのデータソースではないため、UICollectionViewのリロードが完了した時点を知る必要があります。 ...)reloadDataメソッドを使用したUICollectionViewのリロードは、データのリロード直前に戻ります。

私は、このような私はダをリロードするとき、私はまた

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView reloadData]; 
    } completion:^(BOOL finished) { 
     // notify that completed and do the configuration now 
    }]; 

しかしを使用してみました

[self.collectionView reloadData]; 
[self configure cells]; // BOOM! cells are nil 

などのコードを試してみました私はクラッシュしています。これはreloadDataでlayoutSubviewsない時に追加された細胞によって引き起こされる特定の完了ハンドラを行う

+0

私はsimmilar問題が発生したと思います。問題は、次の実行ループパス中に起こるlayoutSubview中にセルがロードされることです。残念ながら私はまだ解決策を見つけられませんでした。 UICollectionViewDelegateのような方法ではありませんなぜ私が疑問に思う: を - collectionView:willBeginDisplayingCell:forItemAtIndexPath: がありながら: - collectionView:didEndDisplayingCell:forItemAtIndexPath: あなたはすでに1つを解決しましたか? – lukewar

+0

何が起こっているかは、バッチ更新ブロックでは、リロード中に発生する新しい行数とセクション数に対応する行/セクションの追加と削除を呼び出すことを期待しています。これが発生しない場合、アサーションがスローされます。 –

答えて

81

-

はどのようにして、コレクションにデータをリロードすることができ、それがリロードを終了したときにのみ。 layoutSubviewsは、reloadDataの次の実行ループパスで実行されるため、セルは空です。 これをやってみてください。

[self.collectionView reloadData]; 
[self.collectionView layoutIfNeeded]; 
[self configure cells]; 

私は同様の問題を持っていたし、それをこのように解決しました。

+12

素晴らしい答えが受け入れられるはずです。 –

+1

'-reloadData'を呼び出した後に' visibleCells'が0だったのと全く同じ問題がありました。 '-layoutIfNeeded'を呼び出すとこれが修正されました。 lukewarの答えは受け入れられるべきです。 –

+1

完璧なもの。受け入れられるべきである。 –

5

reloadDataのヘルプを使用して、アニメーションでリロードすることはできません。すべてのアニメーションは、

[collectionView deleteItemsAtIndexPaths:indexesToDelete]; 
[collectionView insertSections:sectionsToInsert]; 
[collectionView reloadItemsAtIndexPaths:fooPaths]; 

performBatchUpdates:ブロックのようなメソッドで実行する必要があります。そのreloadDataメソッドは、すべてのアイテムが削除され、アニメーションなしで再びレイアウトされた場合に、粗いリフレッシュにのみ使用できます。

+0

私はリフレッシュとAPIの応答のプルの間にレースを持っていたとこれが助けた。 reloadDataの代わりにリロードするセクションを削除して挿入するだけです。self.collectionView?.performBatchUpdates({ self.collectionView?.deleteSections(IndexSet(arrayLiteral:0)) self.collectionView?.insertSections(IndexSet(arrayLiteral) :0)) }、完了:なし) ' –

4

あなたcollectionViewはそれがreloadData()メソッドの完了した後にあなたには、いくつかのコードを実行したい場合は、(スウィフト)これを試してみてください。この作品

self.collectionView.reloadData() 
    self.collectionView.layoutIfNeeded() 
    dispatch_async(dispatch_get_main_queue()) {() -> Void in 
     // Put the code you want to execute when reloadData is complete in here 
    } 

理由は、ディスパッチブロック内の理由コードです行の裏側に置かれます(キューとも呼ばれます)。これは、reloadData()のメソッドを含む、すべてのメインスレッドの処理が完了するのを待っていることを意味します。

+1

よく、これは完全ではない、いくつかのメインスレッド操作の間にディスパッチブロックを挿入することができます。http://stackoverflow.com/a/10450867/4003774を参照してください。しかし、あなたのコードはlayoutIfNeededのおかげで(dispatch_asyncを使わなくても)動作します(@ lukewarの答えを見てください) –

関連する問題