タイトルが示すように、私のUICollectionView
は、reloadData
を呼び出した直後にセルを更新および表示しません。代わりに、30〜60秒後にコレクションビューが最終的に更新されるようです。私の設定は次のとおりです。
ストーリーボードのビューコントローラーにUICollectionView
が追加され、ビューコントローラーのdelegate
とdataSource
の両方のセットアップと標準のコンセントのセットアップnumberOfSectionsInRow
&cellForItemAtIndexPath
が追加されましたプロトタイプ化されたセルとその中のimageView
を実装し、参照します
これは、Twitterにアクセスし、タイムラインを取得して変数に割り当て、ツイートを含むテーブルビューを再読み込みしてから、ツイートを調べて写真を検索し、コレクションビューにそれらのアイテムを再読み込みするコードです。
画像を表示するコードをコメントアウトしても、何も変わりません。
SLRequest *timelineRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:timelineURL parameters:timelineParams];
[timelineRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if(responseData) {
JSONDecoder *decoder = [[JSONDecoder alloc] init];
NSArray *timeline = [decoder objectWithData:responseData];
[self setTwitterTableData:timeline];
for(NSDictionary *Tweet in [self twitterTableData]) {
if(![Tweet valueForKeyPath:@"entities.media"]) { continue; }
for(NSDictionary *photo in [[Tweet objectForKey:@"entities"] objectForKey:@"media"]) {
[[self photoStreamArray] addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[photo objectForKey:@"media_url"], @"url",
[NSValue valueWithCGSize:CGSizeMake([[photo valueForKeyPath:@"sizes.large.w"] floatValue], [[photo valueForKeyPath:@"sizes.large.h"] floatValue])], @"size"
, nil]];
}
}
[[self photoStreamCollectionView] reloadData];
}
}];
これは、バックグラウンドスレッドからUIKitメソッドを呼び出すことの典型的な症状です。 _-[SLRequest performRequestWithHandler:]
_ドキュメント を表示すると、ハンドラーはどのスレッドで実行されるかを保証しないと表示されます。
reloadData
への呼び出しをブロックにラップし、これをdispatch_async()
に渡します。また、キュー引数としてdispatch_get_main_queue()
を渡します。
更新をメインスレッドにディスパッチする必要があります。
dispatch_async(dispatch_get_main_queue(), ^{
[self.photoStreamCollectionView reloadData];
});
またはSwiftで:
dispatch_async(dispatch_get_main_queue(), {
self.photoStreamCollectionView.reloadData()
})
Appleのコメント:アイテムが挿入または削除されているアニメーションブロックの途中でこのメソッドを呼び出さないでください。挿入と削除により、テーブルのデータが自動的に適切に更新されます。
正面:アニメーションの途中でこのメソッドを呼び出さないでください(スクロールにUICollectionViewを含めます)。
だからあなたはできる:
[self.collectionView setContentOffset:CGPointZero animated:NO];
[self.collectionView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
または、アニメーションがないことを確認してから、reloadDataを呼び出します。または
[self.collectionView performBatchUpdates:^{
//insert, delete, reload, or move operations
} completion:nil];