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
}