データ非同期で読み込むUITableviewがあるので、テーブルビューがデータなしで表示される可能性があります。
ReloadDataメソッドに疲れましたが、テーブルビューをスクロールするまでテーブルビューは空のままで、突然データが表示されます。
テーブルビューを詳細ビューとして読み込んでアイテムを切り替えると、同じことが起こります。前のアイテムのデータが最初に表示され、テーブルビューをスクロールするとすぐに正しいデータが表示されます。
私の推測では、ReloadDataメソッドは正常に動作しますが、どうにかしてテーブルビューを再描画する必要があります。これを解決する方法に関する提案はありますか?
/ジミー
コンテンツを非同期的に入力していると言いましたが、メインスレッドのコンテキストでreloadDataを呼び出しましたか? (コンテンツを入力するスレッドを介さない)
Objective-C
[yourUITableView performSelectorOnMainThread:@selector(reloadData)
withObject:nil
waitUntilDone:NO];
スウィフト
dispatch_async(dispatch_get_main_queue(), { self.tableView.reloadData() })
モノタッチ
InvokeOnMainThread(() => this.TableView.ReloadData());
Yonelsの回答は、ビューが現在ユーザーに表示されている場合に最適です(例:ユーザーがUITableView
に入力する再読み込みボタンを押します)。
ただし、データが非同期で読み込まれ、更新中にUITableView
が表示されない場合(例:別のビューでUITableView
にデータを追加し、UITableView
が後で表示されるuserinputによって)、UITableViewController
のviewWillAppear
メソッドをオーバーライドするだけです。
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.tableView reloadData];
}
プラスの効果は、UITableView
がデータを再読み込みするのは、新しいアイテムが追加されたときではなく、ユーザーが実際に見たいときに1回だけであることです。
リロードされなかったと思います。
セルを画面外にスクロールすると、…
tableView: cellForRowAtIndexPath:
…呼び出されます。したがって、リロードされます。
UITableView変数が検証されていないと思います。
UITableViewをメインビューとして使用する場合は、これを試すことができます。
[self.view reloadData];
または
[self.tableView reloadData];
今日も同様の問題がありました(iOS 7.0のストーリーボード)。 UIViewController内でテーブルビューを使用していました。ビューが読み込まれたとき、すべてが正常に機能していました。代議員全員が呼ばれていました。基になるdataSource(私の場合は、Array)が変更されたとき。表示されているテーブル行が更新されていませんでした。テーブルビューをスクロールしていたときのみ。
すべてを試しました。メインスレッドでreloadDataを呼び出す、ViewWillAppearでreloadを呼び出す、何もうまくいきませんでした。
私が見つけた問題。ストーリーボードで接続していなかったということです。参照Outletを持つテーブルビューの場合。dataSourceとデリゲートは設定されました。それが問題になるとは思いませんでした。最初の段階ではすべてが正常に機能していたため。
それが誰かを助けることを願っています。私はこれを見つけるためにひどい時間を過ごしました。
Swift 4:
DispatchQueue.main.async { self.tableView.reloadData() }
Yonelのソリューションを多少素朴にコピーしてそれを適切に呼び出すと、performSelectorOnMainThread:withObject:waitUntilDone:
を呼び出すと症状が修正されるが、問題は修正されないことに気付きました。より大きな問題は、非同期またはバックグラウンドスレッドのコンテキストでUIを更新していることです。
これは私のコードがどのように見えるかです:
dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL);
dispatch_async(queue, ^{
// Make API call
// Retrieve data, parse JSON, update local properties
// Make a call to reload table data
});
次のようになるはずです:
dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL);
dispatch_async(queue, ^{
// Make API call
// Retrieve data, parse JSON, update local properties
dispatch_async(dispatch_get_main_queue(), ^{
// Now make the call to reload data and make any other UI updates
[self.tableView reloadData]
});
});
onlyを行う必要がある場合は、[self.tableView reloadData]
を呼び出すことです。同じ目的を達成するため、performSelectorOnMainThread:withObject:waitUntilDone:
を使用することはおそらく問題ありません。しかし、全体像で何が起こっているかを認識する必要もあります。また、単にテーブルをリロードするだけではなく、より多くのUI作業を行っている場合は、そのすべてのコードもメインキューに配置されます。
参照: 簡潔な例 GCDを使用し、バックグラウンドとメインスレッドを管理する方法。