Подтвердить что ты не робот

CellForRowAtIndexPath: не называется

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

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

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

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

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

Спасибо,
S.

EDIT: Здесь асинхронный бит кода из 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];
        }
    }];
}

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

Ответ 3

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

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

Ответ 4

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

Ответ 5

// For others showing up on this questions via Google, etc.
// Check and make sure you've set the table view data source and delegate.
self.tableView.dataSource = self;
self.tableView.delegate = self;

Ответ 6

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

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

// False
    ▼ View
        ► Scrool View
            ► Table View
        ► Constraints

Ответ 7

Все говорят о высоте, но мой TableView в StackView с ведущим выравниванием заканчивается шириной 0.

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

Ответ 8

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

Ответ 9

Это смущает и озадачивает, но здесь мое решение.

Мой код:

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

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

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

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

Ответ 10

Я использую ReactiveCocoa. Итак, я создал модель для табличного представления. Данные были подготовлены для отображения, поэтому был вызван numberOfRows и так далее. Но я не добавил табличное представление как подпредставление, поэтому cellForRowAtIndexPath не был вызван)))

Ответ 11

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Make sure self.data isn't nil!
    // If it is, you'll always return 0 and therefore
    // cellForRowAtIndexPath will never get called.
    return [self.data count]; 
}

Ответ 12

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

Ответ 13

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

tableView?.translatesAutoresizingMaskIntoConstraints = false

Глупая ошибка с моей стороны.

Ответ 14

Вы уверены, что после того, как пользователь вошел в систему и B выскочил, метод viewWillAppear в будет вызван для выполнения обновления?

Если вы показываете B как модальный контроллер, при его отклонении вы не будете вызывать метод viewWillAppear.

Насколько я знаю, viewWillAppear/viewDidAppear (и другие подобные ему) являются событиями, генерируемыми UINavigationController в случае событий навигации (push/pop viewcontrollers). Поэтому, возможно, именно поэтому вы в конечном итоге получаете свое обновление, когда вы покидаете A и возвращаетесь... все зависит от способа отображения следующего диспетчера представлений.

Ответ 15

Попробуйте вставить новые строки вручную вместо [self.tableView reloadData]:

[self.tableView beginUpdates];
    for (int i = 0; i < responseArray.count; i++) {
        _rowsNumber += 1;
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
        [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
    }
[self.tableView endUpdates];

В методе dataSource return incremented int _rowsNumber:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _rowsNumber;
}

Ответ 16

Я решил такую ​​же проблему, проверив идентификатор tableViewCell. Перейдите к атрибутам İnspector и посмотрите раздел идентификатора. Наверное, отсутствует. Поэтому напишите идентификатор ячейки.

Ответ 17

В этом же случае, но это была ошибка:

Я включил Scrollview с двумя таблицами внутри ViewController (требования к дизайну), в контроллере scrollview я создал программный пакет ViewControllers (который содержит TableViews), и я использовал слабый var для его хранения, Плохая идея, потому что они были выпущены в конце метода viewDidLoad.

Если вы не видите свой контент в таблице, пожалуйста, проверьте, был ли он выпущен.

Моя ошибка была очень болезненной для меня, потому что были вызваны все методы (delegate & datasource), кроме viewForCell...

Ответ 18

У меня такая же проблема я использую Table View внутри StackView и прокрутки таблицы view отключить и установить ограничение высоты, но после этого

tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

Не работает. Прекратите вызывать этот метод для всех Data Source и Delegate.

если у вас есть такая же проблема, чем у решения установлено Table View bottom, leading, trailing constrain

введите описание изображения здесь

Ответ 19

Ни один из ответов здесь не помог мне.

Я использовал программные ограничения, но забыл написать:

myTableView.translatesAutoresizingMaskIntoConstraints = false

Ответ 20

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

Ответ 21

В моем случае у меня был TableView внутри StackView. Ru enter code here ru Я поместил его вне StackView, он работал.

Ответ 22

check numberOfRowsInSection не 0. иногда это 0, и никто его не узнает.