applicationWillEnterForegroundのイベントが発生した時にサーバから最新情報を取得して画面の更新を行う手法を他でもされているので、それらのお手本に従って実装しようとしているのですがUICollectionView(利用しているのはマテリアルコンポーネントのMDCCollectionViewController)がreloadDataを行った後に画面が更新されていません。
applicationWillEnterForeground時にお手本通りNotificationを利用してViewController処理呼び出し
objc
1-(void)applicationWillEnterForeground:(UIApplication *)application { 2 3 __strong NSNotification *notification = [NSNotification notificationWithName:@"applicationWillEnterForeground" object:self]; 4 [[NSNotificationCenter defaultCenter] postNotification:notification]; 5} 6
Notification登録
objc
1-(void)viewDidLoad { 2 NSLog(@"%s", __PRETTY_FUNCTION__); 3 [super viewDidLoad]; 4 5 // notification center setup 6 __weak NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 7 [center addObserver:self 8 selector:@selector(applicationWillEnterForeground) name:@"applicationWillEnterForeground" 9 object:nil]; 10} 11
APIを呼び出した結果はself.costResultsに入ります。
以下がUICollectionViewのreloadData処理
objc
1-(void)applicationWillEnterForeground { 2 NSLog(@"%s", __PRETTY_FUNCTION__); 3 4 self.costResult.costDate = [NSDate date]; 5 NSLog(@"%@", self.costResult.costDateStr); 6 7 [self.costResults reload:self 8 doneEvent:@selector(updateAfterForeground:) 9 costResult:self.costResult]; 10 11} 12 13-(void)updateAfterForeground:(WebAPI *)webAPI { 14 15 if (webAPI.isError) { 16 [self showStatus:webAPI.error.localizedDescription 17 completion:^{ 18 [self.collectionView reloadData]; 19 [self.collectionView layoutSubviews]; 20 }]; 21 } else { 22 [self.collectionView reloadData]; 23 [self.collectionView layoutSubviews]; 24 [self showCurrentDate]; 25 } 26} 27
上記ではお作法に反してlayoutSubViewsを使っていますが、layoutIfNeededでも上手くいきませんでした。
objc
1/* ************************************************************************************************* 2 * cell for item 3 * ************************************************************************************************/ 4 5-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 6 cellForItemAtIndexPath:(NSIndexPath *)indexPath { 7 8 switch (indexPath.row) { 9 case 0: { 10 if (self.costResult.isMapMode) { 11 return [self cellForMap:collectionView indexPath:indexPath]; 12 } else { 13 return [self cellForInput:collectionView indexPath:indexPath]; 14 } 15 } 16 case 1: { 17 return [self cellForSummary:collectionView indexPath:indexPath]; 18 } 19 default: { 20 return [self cellForCostResults:collectionView indexPath:indexPath]; 21 } 22 } 23} 24 25/* 略 */ 26/* ================================================================================================= 27 * cell for item - cell for summary 28 * ============================================================================================== */ 29 30-(UICollectionViewCell *)cellForSummary:(UICollectionView *)collectionView 31 indexPath:(NSIndexPath *)indexPath { 32 NSLog(@"%s", __PRETTY_FUNCTION__); 33 34 __strong NSString *identifier = nil; 35 identifier = NSStringFromClass([CostResultSummaryCell class]); 36 __strong CostResultSummaryCell *summaryCell = nil; 37 summaryCell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier 38 forIndexPath:indexPath]; 39 [summaryCell populateContent:self.costResults]; 40 41 return summaryCell; 42} 43
cellForAtも追加しました。
データソース更新の処理が正しく呼ばれているかチェックしましたが、numberOfItemsInSections/cellForItemAtIndexPath共に正しく呼ばれて処理されていましたが、表示だけが更新されません。
セルの再利用が影響しているのかと思い、prepareForReuseを利用してセル内のデータはクリアを行なっていますが、改善しません。
また、当現象はアプリケーションがバックグラウンドからフォアグラウンドに移行した時(applicationWillEnterForeground)からのreloadDataのみ発生します。そもそもreloadDataがうまくいってないんじゃないか?と思われるかもしれませんが、アプリケーション起動中に画面遷移、ボタンによるonTapイベント時にもAPI呼び出しからのreloadDataを行なっており、これらは正常に動いています。
また、reloadDataはメインスレッドで動いています。
(メインスレッド以外から呼び出されると動きが不安定になる?という仕様があったため、ねんのため確認しましたがメインスレッドでの処理でした)
改善するべき点、または回避可能なアイデアはありますでしょうか?
ご教授宜しくお願いいたします。
回答1件
あなたの回答
tips
プレビュー