UICollectionView cellForItemAtIndexPath не вызывается

Только во второй раз, используя UICollectionView, и, возможно, я откусил больше, чем я могу жевать, но тем не менее:

Я реализую UICollectionView (myCollectionView), который использует пользовательский UICollectionViewCell, который я подклассифицировал. Подклассифицированные ячейки (FullReceiptCell) содержат UITableView и являются размерами диспетчера представлений. Я пытаюсь разрешить горизонтальную прокрутку между FullReceiptCells.

Подклассифицированный UICollectionViewController, содержащий myCollectionView, переносится в стек контроллера контроллера. В настоящее время включена функция myCollectionView loas и горизонтальная прокрутка. Однако никаких ячеек не видно. Я подтвердил, что

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

выполнил и возвращает целое число, большее 0. Я также подтвердил, что делегат myCollectionView и источник данных правильно установлены в IB для подкласса UICollectionViewController.

Метод, в который должны быть загружены ячейки:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

не вызывается.

Здесь я нажимаю UICollectionViewController и мой метод viewDidLoad внутри этого контроллера (ПРИМЕЧАНИЕ: initWithBill является переопределением нормального инициализатора):

В предыдущем файле ViewControllers.m:

FullReceiptViewController *test = [[FullReceiptViewController alloc] initWithBill:currentBill];
test.title = @"Review";
[self.navigationController pushViewController:test animated:YES];

В FullReceiptViewController.m:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    [self.myCollectionView registerClass:[FullReceiptCell class] forCellWithReuseIdentifier:@"FullReceiptCellIdentifier"];
    self.myCollectionView.pagingEnabled = YES;
    // Setup flowlayout

    self.myCollectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
    [self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];
    [self.myCollectionViewFlowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    [self.myCollectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    self.myCollectionViewFlowLayout.minimumLineSpacing = 0;
    self.myCollectionViewFlowLayout.minimumInteritemSpacing = 0;
    [self.myCollectionView setCollectionViewLayout:myCollectionViewFlowLayout];
    //testing to see if the collection view is loading
    self.myCollectionView.backgroundColor = [UIColor colorWithWhite:0.25f alpha:1.0f];

Любая подсказка о том, почему она не называется?

Ответ 1

Для тех, кто споткнется здесь позже... причина:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

не вызывался из-за того, что itemSize для heightViewFlowLayout был слишком большим.

[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];

Если я изменю высоту до 410, она выполнит cellForItemAtIndexPath.

Ответ 2

В моем случае это произошло потому, что мой класс макета неправильно подклассифицирован из UICollectionViewLayout вместо UICollectionViewFlowLayout

Ответ 3

CellForItemAtIndexPath не будет вызван, если вы не предоставите информацию о размере содержимого в виде коллекции.

  • Если вы используете раскладку Flow: вам нужно правильно установить размеры элементов.
  • Если у вас есть пользовательский макет подкласса из UICollectionViewLayout: убедитесь, что вы возвращаете правильный размер из метода collectionViewContentSize.

В случае последнего вы также заметите, что ваш layoutAttributesForElementsRect также не вызывается. Причина в том, что вы не указали, каков ваш размер контента, и по умолчанию размер будет CGSizeZero. Это в основном показывает представление коллекции, что у вас нет контента для рисования, поэтому он не беспокоится о том, чтобы запрашивать атрибуты или ячейки.

Итак, просто переопределите collectionViewContentSize и предоставьте правильный размер там, он должен решить вашу проблему.

Ответ 4

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

<UICollectionViewDelegate, UICollectionViewDataSource>

и в вашем методе viewDidLoad добавьте это:

self.myCollectionView.delegate = self;
self.myCollectionView.dataSource = self;

Кроме того, если вы загружаете его через .xib, убедитесь, что вы подключили IBOutlet к UICollectionView.

Ответ 5

Для более сложного просмотра иерархии, пожалуйста, просмотрите этот блог. Это спасло мою жизнь!

self.automaticallyAdjustsScrollViewInsets = NO;

Ответ 6

Если ваш класс является подклассом из UICollectionviewController и вы создаете collectionView программно, тогда используйте

let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .Vertical
    layout.itemSize = CGSizeMake(50, 50)

    collectionView?.setCollectionViewLayout(layout, animated: false)

Ответ 7

Я использовал автозапуск, и в моем случае ограничение по высоте отсутствовало

Ответ 8

В моем случае то, что я очень глупо забыл сделать, это реализовать метод протокола UICollectionViewDataSource numberOfItemsInSection, так что это еще одна вещь, которую нужно проверить.

Ответ 9

Моя проблема заключалась в том, что у меня было 2 представления коллекции в одном представлении, и оба они делили вычисляемый экземпляр UICollectionViewFlowLayout. Когда я создал отдельные экземпляры одного и того же макета потока, он работал нормально.

Ответ 10

Это произошло для меня, когда item height == 0, установив, что метод cellForItem был вызван.

Ответ 11

Десять минут назад я также столкнулся с этой проблемой, я сделал глупую ошибку.

Я намерен использовать UICollectionViewFlowLayout,

Но из-за ошибок я использовал UICollectionViewLayout.

Ответ 12

В моем случае изменение UINavigationBar, полупрозрачного до NO, решило проблему.

Ответ 13

В Xcode 7.0.1 мы получили эту проблему, когда мы скопировали раскадровку и сопроводительный код из другого проекта. В представлении коллекции был настроен собственный макет потока, установленный в раскадровке. Решение было:

  • Удалите компоновку потока в IB
  • Скомпилировать/запустить приложение
  • Установите раскладку потока

Теперь это сработало:)

Ответ 14

Убедитесь, что numberOfSectionsInCollectionView также возвращает положительное целое число.

В коллекции должен быть хотя бы один раздел.

Ответ 15

Убедитесь, что - (NSInteger) collectionView: numberOfItemsInSection: возвращает положительное (прочитанное, большее, чем ноль) значение. Это может быть вопрос размещения [self.collectionView reloadData]; в обработчике завершения.

Ответ 16

Я забыл установить маску авторезистировки на false в представлении коллекции:

collectionView.translatesAutoresizingMaskIntoConstraints = false

Ответ 17

Если вы используете протоколы представления коллекции, вы должны подключить протоколы CollectionViewDataSource и CollectionViewDelegate к вашему ViewController. Interface builder outlets

Ответ 18

Это могут быть решены проблемы макета. Проверьте предупреждения макета с консоли, если они существуют.

Ответ 19

В моем случае представление коллекции не было полностью видимым в его родительском представлении из-за неправильных ограничений макета. Таким образом, фиксация ограничений сделала просмотр коллекции видимым и вызывался cellForItemAtIndexPath.

Ответ 20

В раскадровке /XIB UICollectionView свойство cellSize НЕ ДОЛЖНО быть {0, 0}

Ответ 21

То же самое случилось со мной. У меня было 2 UICollectionViews, и я удалил один раз, так как мне это не нужно. После этого я понял, что CellForItemAtIndexPath не вызывается, а другие необходимые методы. Я попробовал все вышеперечисленное, но затем сделал стандартную магию. Удалено представление коллекции из раскадровки и добавлено снова. Затем он начал работать. Не знаю, почему и у меня нет объяснений, но, возможно, некоторые проблемы с подключением.

Ответ 22

Кроме того, убедитесь, что reloadData не вызывается, когда просмотр коллекции обновляется с помощью анимации (вставка, удаление, обновление или выполнениеBatchUpdates).

Ответ 23

В моем случае set collectionView.prefetchingEnabled = NO; решил мою проблему. Работает только на iOS 10.

Ответ 24

При использовании UICollectionViewDelegateFlowLayout будьте осторожны с тем, что возвращает эта функция. Оба width и height должны быть больше, чем 0. Я использовал window как ссылку на фрейм, но из-за сложного окна иерархии просмотров было nil во время выполнения. Если вам нужно настроить ширину элемента на основе ширины экрана, используйте UIScreen.main.bounds.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: 
           UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {}

Ответ 25

У меня была такая же проблема. Пробыв несколько часов с различными приемами, то, что сработало для меня, было: - перезапустить Xcode. Мой cellforitematindexpath был вызван, и ячейки были правильно заполнены изображениями

Ответ 26

Для меня я обновляю высоту self.view(viewView viewView) через автозапуск и ДОЛЖЕН вызывать layoutIfNeeded после этого.

[self.view mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.equalTo(@(height));
}];
[self.view layoutIfNeeded];

Ответ 27

Просто разрешила эту проблему для некоторой конкретной ситуации.

В моем случае я вручную инициализировал UICollectionViewController в родительском ViewController, а затем добавил представление UICollectionViewController в качестве подзадачи.

Я решил проблему, вызвав "setNeedsLayout" и/или "setNeedsDisplay" в коллекцииView в родительском представленииDidAppear:

- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   [_collection.view setNeedsLayout];
   [_collection.view setNeedsDisplay];
}

Ответ 28

Я немного потоплю эту проблему с помощью CollectionView в контроллере Contained, загруженном из раскадровки. Я закончил тем, что просто удалил скрытый контроллер представлений и воссоздал его в раскадровке, и это, казалось, избавилось от этой проблемы. Я предполагаю, что произошла какая-то коррупция в раскадровке, которая произошла.

Ответ 29

Настройка коллекции frameView внутри пользовательского сокета layoutSubViews() работал у меня:

override func layoutSubviews() {
        super.layoutSubviews()
        let frame = self.contentView.bounds
        self.CollectionView.frame = frame
    }