Перерисовать UITableView после обновления данных асинхронно - PullRequest
24 голосов
/ 24 февраля 2010

У меня есть UITableview, который я загружаю с асинхронностью данных, чтобы табличное представление могло отображаться без данных.
Я устал от метода ReloadData, но табличное представление остается пустым, пока я не прокручиваю табличное представление, внезапно данные появляются.
То же самое происходит, когда я загружаю табличное представление как подробное представление и переключаюсь между элементами, сначала отображаются данные предыдущих элементов, и как только я прокручиваю в табличном представлении, они показывают правильные данные. Я предполагаю, что метод ReloadData работает просто отлично, но мне нужно как-то перерисовать табличное представление, какие-либо предложения о том, как решить эту проблему?

/ Jimmy

Ответы [ 6 ]

54 голосов
/ 24 февраля 2010

Вы сказали, что заполняете контент асинхронно, но вы вызывали reloadData в контексте основного потока? (а не через поток, который заполняет контент)

Objective-C

[yourUITableView performSelectorOnMainThread:@selector(reloadData)
                                  withObject:nil 
                               waitUntilDone:NO];

Swift

dispatch_async(dispatch_get_main_queue(), { self.tableView.reloadData() })

MonoTouch

InvokeOnMainThread(() => this.TableView.ReloadData());
4 голосов
/ 08 января 2013

Ответ Yonels идеален, когда ваш вид в настоящее время виден пользователю (например, пользователь нажимает кнопку перезагрузки, которая заполняет ваш UITableView.)

Однако, если ваши данные загружаются асинхронно и ваш UITableView не виден во время обновления (например: вы добавляете данные в UITableView в другом представлении, а UITableView отображается позже при входе пользователя), просто переопределите метод UITableViewController viewWillAppear.

- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.tableView reloadData];
}

Положительный эффект заключается в том, что UITableView перезагружает свои данные только один раз, когда пользователь действительно хочет их видеть, а не при добавлении новых элементов.

2 голосов
/ 08 февраля 2014

У меня была похожая проблема сегодня (раскадровка в iOS 7.0). Я использовал табличное представление внутри UIViewController. Когда представление загружалось, все работало нормально; все делегаты были вызваны. Однако; Когда базовый источник данных (в моем случае, массив) был изменен; видимые строки таблицы не обновлялись. Они обновлялись; только когда я прокручивал представление таблицы.

все перепробовал; вызов reloadData в главном потоке, вызов reload в ViewWillAppear; ничего не получалось.

Проблема, которую я обнаружил; было то, что я не установил связь в раскадровке; для табличного представления со ссылкой Outlet. DataSource и делегат были установлены, хотя. Я не думал, что это может быть проблемой; как все работало нормально с первого раза.

Надеюсь, это кому-нибудь поможет. У меня было ужасное время, чтобы это выяснить.

2 голосов
/ 24 февраля 2010

Полагаю, оно не было перезагружено.

Когда вы прокручиваете ячейки вне экрана, тогда…

tableView: cellForRowAtIndexPath:

… будет называться. Так что он будет перезагружен.

Я думаю, переменная UITableView не проверена.

Если вы используете UITableView в качестве основного вида, вы можете попробовать это.

[self.view reloadData];

или

[self.tableView reloadData];

1 голос
/ 21 января 2019

Swift 4:

DispatchQueue.main.async { self.tableView.reloadData() }
0 голосов
/ 06 марта 2014

После некоторого наивного копирования решения Йонеля и признания его хорошим, я понял, что вызов performSelectorOnMainThread:withObject:waitUntilDone: исправил симптом, но не проблему. Большая проблема заключается в том, что вы делаете обновления пользовательского интерфейса, находясь в контексте асинхронного или фонового потока.

Вот как выглядел мой код:

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:, поскольку он выполняет ту же цель, но вы также должны понимать, что происходит в целом. Кроме того, если вы выполняете больше работы с пользовательским интерфейсом, чем просто перезагружаете таблицу, тогда весь этот код также должен попадать в основную очередь.

Ссылка: Краткий пример использования GCD и управления фоном и основным потоком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...