cellForRowAtIndexPath: не вызывается - PullRequest
66 голосов
/ 10 октября 2011

Мое приложение имеет два состояния: вошел в систему и не вошел в систему, и у меня есть следующая архитектура (значительно упрощенная):
- ViewController A, который содержит поле поиска и табличное представление.
- ViewController B, которыйиспользуется для входа в приложение.

Поток следующий:
- пользователь не вошел в систему;
- A помещается в стек.В viewWillAppear я проверяю, вошел ли пользователь в систему и, если да, выполняется асинхронный сетевой запрос, и, как только это будет сделано, таблица загружается данными из сети.Однако, поскольку пользователь не вошел в систему на этом этапе, табличное представление пусто;
- пользователь нажимает на поле поиска;поскольку он не вошел в систему, B нажимается (после подтверждения);
- он успешно входит в систему B, затем нажимает кнопку, которая выдает B и снова показывает A;
- в этот момент времени, потому что онвошел в систему, с viewWillAppear я делаю асинхронный запрос;
- когда это будет выполнено, я вызываю reloadData в табличном представлении.

Я замечаю, что numberOfRowsInSection: вызывается ивозвращает правильный результат, однако cellForRowAtIndexPath: впоследствии НЕ вызывается, и таблица остается пустой.

Я проверил, и reloadData вызывается в главном потоке.

Любая идея, что можетэто будет?Потому что это сводит меня с ума!

Спасибо,
S.

РЕДАКТИРОВАТЬ: Вот асинхронный бит кода из viewWillAppear в A.

if ([User isLoggedIn]) {
    [self.asyncRequest fetchDataWithCompletionHandler:^(id response, NSError *error) {
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        if (error) {
            [Utils displayError:error];
        } else {
            self.array = response;

            self.isLoaded = YES;
            [self.tableView reloadData];
            [self.tableView setContentOffset:CGPointMake(0.0f, 0.0f) animated:NO];
        }
    }];
}

Iпроверил, что асинхронный запрос успешно завершен и что response содержит правильные данные (это массив, используемый для поддержки UITableView).

После reloadData я установил точку останова в tableView:numberOfRowsInSection:, и она останавливается там, и возвращает правильное количество элементов в array.Однако после этого точка останова в tableView:cellForRowAtIndexPath: никогда не будет достигнута.

Ответы [ 20 ]

243 голосов
/ 20 февраля 2012

Один действительный сценарий того, почему numberOfRowsInSection будет вызываться, но cellForRowAtIndexPath не будет вызван, - это когда размер или расположение таблицы не требуют отображения каких-либо строк.

Например, допустим, у вас была таблица, высота которой составляла 20 пикселей, но заголовок первого раздела имел высоту 30, и вы вернули nil для заголовка (или не реализовали viewForHeaderInSection). В этом случае строки не будут отображаться, и будет выглядеть так, будто таблицы просто нет.

Я вижу, вы используете IB. Размер таблицы может быть обманчивым в IB, так как он предполагает размеры верхнего и нижнего колонтитула. Я бы зарегистрировал фрейм для таблицы, чтобы вы понимали, где она находится, когда запускается приложение (по сравнению с тем, где оно появляется в IB). Я также был бы уверен, что размер таблицы и ее размещение вручную будут перед вызовом reloadData. Это решит этот допустимый случай, когда cellForRowAtIndexPath не вызывается.

39 голосов
/ 14 марта 2012

Убедитесь, что numberOfSectionsInTableView не возвращает 0.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}
22 голосов
/ 06 февраля 2013

У меня была точно такая же проблема, и проблема была в том, что я пытался вызвать reloadData: из другого потока. Решение будет:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.tableView reloadData];
});
13 голосов
/ 16 августа 2016

Если вы используете другой источник данных, как я, убедитесь, что вы сохраняете источник данных.Простого создания экземпляра класса, который будет являться источником данных, и назначения его с помощью tableView.dataSource = myDataClass будет недостаточно, поскольку свойство dataSource табличного представления является слабым и будет освобождено после завершения viewDidLoad.Все остальные методы были вызваны для меня - даже, к удивлению, heightForRowAtIndexPath - поэтому мне потребовалось некоторое время для отладки.

12 голосов
/ 30 марта 2014
// For others showing up on this questions via Google, etc.
// Check and make sure you've set the table view's data source and delegate.
self.tableView.dataSource = self;
self.tableView.delegate = self;
8 голосов
/ 15 декабря 2014

Если табличное представление внутри представления, которое конфликтует с чем-то вроде Scrool View, оно не вызывается.Вы должны разделить представления в вашем раскадровке или * .xib файле.

// True
    ▼ View
        ► Table View
        ► Scrool View
        ► Constraints

// False
    ▼ View
        ► Scrool View
            ► Table View
        ► Constraints
3 голосов
/ 13 января 2017

Все продолжают говорить о высоте, но мои TableView в StackView с ведущим выравниванием закончились с шириной 0

Убедитесь, что ваш TableView имеет правильный размер, используя Debug View Hierarchy.

2 голосов
/ 09 сентября 2014

Я решил проблему, потому что мое подпредставление, в которое я добавил UITableView, не было выделено, поэтому оно возвращало nill, а tableview не вызывало cellForRowAtIndexPath, но numberOfRowsInSection вызывалось

2 голосов
/ 03 января 2018

Это смущает и ставит в тупик, но вот мое исправление.

Мой код:

_scanResultTable.delegate = self;
_scanResultTable.dataSource = self; // self's lifecycle was fine, wasn't getting released
[_scanResultTable reloadData];

Итак, странная часть такова: идентификатор _scanResultTable никогда не был объявлен в моем коде, нигде впроект.Я понятия не имею, как это скомпилировано (и я перекомпилировал несколько раз).

Моей основной причиной было то, что я связал вывод своей таблицы с scanResultTable в моем ViewController, но ссылался на него как _scanResultTable.Как только я начал использовать scanResultTable, как должен был, все прояснилось.Это заставляет меня задуматься, есть ли у target-c что-то особенное в начальных подчеркиваниях в идентификаторах ...

Редактировать: Это делает !Господи, я не могу дождаться, чтобы никогда больше не трогать этот язык.

1 голос
/ 14 сентября 2016

Я использую источник данных о клиентах, и он был выпущен.Потому что это слабая ссылка на просмотр таблицы.

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