[данные перезагрузки таблицы]; не работает, пока я не прокручу tableView

У меня есть простое приложение, которое загружает результаты поиска в XML, когда пользователь вводит UISearchBar. Загрузка + синтаксический анализ является многопоточным, и после его завершения он запускает NSNotification, чтобы сообщить ViewController с табличным представлением [tableView reloadData];

Вот код, который получает уведомление после получения результатов:

- (void)receivedResults:(id)notification {
    results = [notification object];
    DLog(@"Received %i results",[results count]);
    [[self tableView] reloadData];
}

Я получаю вывод журнала «Получено 4 результата», но табличное представление не перезагружает данные, пока я не прокрутлю/не перетащу его на пару пикселей. Я использую встроенный стиль ячеек UITableViewCellStyleSubtitle, и я не меняю высоту и не делаю ничего необычного с представлением таблицы.

Что я делаю неправильно?


person Maciej Swic    schedule 11.02.2011    source источник
comment
results, конечно, является переменной экземпляра и источником для представления таблицы, иначе приведенный выше код не будет работать даже при перемещении представления таблицы после поиска.   -  person Maciej Swic    schedule 11.02.2011
comment
вы уверены, что [self tableView] не возвращает ноль? Может быть причиной того, что перезагрузка не отвечает, а cellForRowAtIndexPath отвечает. Этот метод вызывается делегатом.   -  person Mats Stijlaart    schedule 19.02.2011


Ответы (5)


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

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

Я думаю, что это более практично, чем опция PerformSelectorOnMainThread.

person The Lazy Coder    schedule 15.08.2012
comment
Не знаю, намного ли это практичнее, однако Apple рекомендует GCD в пользу шаблона PerformSelector.... - person Maciej Swic; 28.02.2013
comment
@MaciejSwic Это должно быть правильное решение этого конкретного вопроса. Проблема в том, что ОП пытается изменить пользовательский интерфейс в фоновом потоке, скорее всего, он забыл выйти из него. Вы не должны вызывать PerformSelectorOnMainThread просто как обходной путь. - person JRam13; 14.10.2014
comment
Это не исправило это для меня. Моя проблема очень похожа, но с той разницей, что ячейки отображают свое содержимое только тогда, когда они полностью прокручиваются из поля зрения и возвращаются в поле зрения. Я пока в полном недоумении... :-( - person Erik van der Neut; 12.05.2015
comment
@ErikvanderNeut Привет, ты решил эту проблему? Я также сталкиваюсь с той же проблемой - person Manimaran; 22.06.2016
comment
Привет @Manimaran - я так и не нашел правильного решения основной проблемы, но с помощью хака я смог заставить его выглядеть так, как будто проблемы не было. Как только это показалось достаточно надежным, я остановился на этом. Мой хак заключался в том, чтобы прокручивать таблицу вперед и назад перед отображением представления. Моя память сейчас немного расплывчата в деталях, но в основном я просто реализовал в коде мгновенную прокрутку вперед и назад, чтобы убедиться, что ячейки были полностью прокручены из поля зрения и возвращены в поле зрения, прежде чем фактически показать это на экране. Звучит абсурдно, но этот уродливый хак решил проблему :-/ Очень странно... - person Erik van der Neut; 16.08.2016

Вызов

[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

вместо

[self.tableview reloadData]
person Andrew    schedule 24.03.2011
comment
Хорошо, я перезагружала свои данные в обработчике событий для NSNotification. - person NMunro; 09.10.2014

Моя проблема заключалась в том, что я публиковал NSNotification из фонового потока. Чтобы избежать этого, просто оберните свой postNotificationMethod в метод dispatch_async следующим образом:

dispatch_async(dispatch_get_main_queue(), ^{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"FinishedDownloading" object:result];
});

Когда это уведомление будет получено, в основном потоке будет вызван tableView.reloadData.

person BalestraPatrick    schedule 30.08.2014

У меня такая же проблема, и я перепробовал все решения, которые смог найти в гугле. Но все они не работают.

Наконец я обнаружил, что добавляю наблюдателя перед viewDidLoad, а затем [self.tableView reloadData] не работает.

Сначала я вызываю setObserverForUserInfoDatabase в viewDidLoad моего корневого контроллера представления навигации. Потому что я думаю, что это было вызвано ранее. Функция такая:

- (void)setObserverForUserInfoDatabase:(NSString *)name {
    [[NSNotificationCenter defaultCenter] addObserverForName:name
                                                      object:nil
                                                       queue:nil
                                                  usingBlock:^(NSNotification *note) {
                                                      [self loadUserInfo];
                                                      [self.tableView reloadData];
                                                      NSLog(@"User Panel Notification \n %@", self);
                                                  }];}

Затем я перемещаю код в viewDidLoad самого viewController.

- (void)viewDidLoad {
    NSLog(@"View Did Load");
    [super viewDidLoad];

    [self setObserverForUserInfoDatabase:UserInfoDataBaseAvailabilityNotification];
}

И тогда все работает нормально.

Я пока не знаю причину. Если кто-нибудь знает, пожалуйста, скажите мне.

person wgr    schedule 13.12.2014
comment
Что делает setObserverForUserInfoDatabase и где он был раньше? - person Maciej Swic; 13.12.2014
comment
Функция просто добавляет наблюдателя. Я поместил его в ViewDidLoad RootViewController. И это не работает. - person wgr; 28.06.2015

перезагрузите свой tableView в viewWillLayoutSubviews

person Krishna Kirana    schedule 19.04.2017