web-dev-qa-db-ja.com

UICollectionViewは、reloadDataを呼び出したときにすぐには更新されませんが、30〜60秒後にランダムに更新されます

タイトルが示すように、私のUICollectionViewは、reloadDataを呼び出した直後にセルを更新および表示しません。代わりに、30〜60秒後にコレクションビューが最終的に更新されるようです。私の設定は次のとおりです。

ストーリーボードのビューコントローラーにUICollectionViewが追加され、ビューコントローラーのdelegatedataSourceの両方のセットアップと標準のコンセントのセットアップnumberOfSectionsInRowcellForItemAtIndexPathが追加されましたプロトタイプ化されたセルとその中の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];
    }
}];
17
nullfox

これは、バックグラウンドスレッドからUIKitメソッドを呼び出すことの典型的な症状です。 _-[SLRequest performRequestWithHandler:]_ドキュメント を表示すると、ハンドラーはどのスレッドで実行されるかを保証しないと表示されます。

reloadDataへの呼び出しをブロックにラップし、これをdispatch_async()に渡します。また、キュー引数としてdispatch_get_main_queue()を渡します。

42
Carl Veazey

更新をメインスレッドにディスパッチする必要があります。

 dispatch_async(dispatch_get_main_queue(), ^{
    [self.photoStreamCollectionView reloadData];
  });

またはSwiftで:

dispatch_async(dispatch_get_main_queue(), {
    self.photoStreamCollectionView.reloadData()
})
8
ricardohdz

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];
3
diong