UICollectionView's cellForItemAtIndexPath is not being called

这只是我第二次使用 UICollectionView,也许我有点吃不消了,但不管怎样:

我正在实现一个 UICollectionView (myCollectionView) ,它使用我已子类化的自定义 UICollectionViewCell。子类单元格(FullReceiptCell)包含 UITableView 的并且是 viewcontroller 的大小。我尝试允许在 FullReceiptCell 之间进行水平滚动。

包含 myCollectionView 的子类 UICollectionViewController 被推送到导航控制器堆栈上。当前,启用了 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];

有没有什么线索,为什么没有被调用?

101808 次浏览

也许我只是忽略了这一点,但似乎你的代表和数据来源不见了。在头文件中,确保添加了以下内容:

<UICollectionViewDelegate, UICollectionViewDataSource>

在 viewDidLoad 方法中添加以下内容:

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

另外,如果通过.xib 加载,请确保已将 IBOutlet 连接到 UICollectionView。

对于那些后来跌跌撞撞来到这里的人... ... 原因是:

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

没有被调用是因为 CollectionViewFlowLayout 的 itemSize 的高度太大。

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

如果我将高度更改为410,它将执行 cellForItemAtIndexPath。

当通过固定 cellForItem 方法被调用时,条目高度 = = 0对我来说就发生了这种情况。

在我的例子中,我非常愚蠢地忘记了实现 UICollectionViewDataSource协议方法 numberOfItemsInSection,因此这是另一件需要检查的事情。

如果不向集合视图提供内容大小信息,则不会调用 cellForItemAtIndexPath。

  1. 如果您正在使用 Flow Layout : 您需要正确设置项目大小。
  2. 如果您有一个从 UICollectionViewLayout 子类化的自定义布局: 请确保您从 CollectionViewContentSize 方法返回适当的大小。

在后者的情况下,您还将注意到您的 < em > layoutAttributesForElementsRect 也没有被调用。原因是您没有指定内容大小,默认情况下大小为 CGSizeZero。这基本上告诉集合视图您没有任何要绘制的内容,因此它不会麻烦地询问您的属性或单元格。

所以,只要覆盖 CollectionViewContentSize 并在那里提供适当的大小,就可以解决问题了。

In my case, it was because my layout class incorrectly subclassed from UICollectionViewLayout instead of UICollectionViewFlowLayout

我也是。我有2个 UICollectionView,我删除了一次,因为我不需要它。在那之后,我意识到 CellForItemAtIndexPath 没有被调用,而是被调用了其他所需的方法。我尝试了以上所有的方法,但是我还是使用了标准的魔法。从故事板中删除了集合视图并再次添加。然后就开始起作用了。不知道为什么,我没有解释,但也许是一些连接问题。

确保 numberOfSectionsInCollectionView也返回一个正整数。

集合中必须至少有一个部分。

确保-(NSInteger) CollectionView: numberOfItemsInSection: 返回正值(read,大于零)。可能需要在完成处理程序中放置[ self. CollectionView reloadData ] ; 。

十分钟前我也遇到了这个问题,我犯了一个愚蠢的错误。

我打算使用 UICollectionViewFlowLayout,

但是由于错误,我使用了 UICollectionViewLayout。

在我的例子中,将 UINavigationBar 的半透明改为 NO 解决了这个问题。

在 Xcode 7.0.1中,当我们从另一个项目中复制一个故事板和附带的代码时,我们遇到了这个问题。集合视图在故事板中设置了一个自定义流布局。解决办法是:

  • 删除 IB 中的流程布局
  • 编译/运行应用程序
  • 将流布局设置回去

现在它奏效了:)

Setting collectionView frame inside custom cell's layoutSubViews() worked for me:

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

For a more complicated view hierachy please check this 博客. It saved my life!

self.automaticallyAdjustsScrollViewInsets = NO;

我花了一点时间来处理这个即将到来的问题,在从故事板加载的包含视图控制器中使用 CollectionView。我最终只是删除了包含的视图控制器,并在故事板中重新创建了它,这似乎解决了问题。我猜是故事板出了问题。

我忘了在集合视图中将自动调整大小的掩码设置为 false:

collectionView.translatesAutoresizingMaskIntoConstraints = false

If your class is subclass from UICollectionviewController and you are creating collectionView programmatically then use

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


collectionView?.setCollectionViewLayout(layout, animated: false)

如果使用集合视图协议,则必须将 CollectionViewDataSourceCollectionViewDelegate协议连接到 ViewController。 Interface builder outlets

Also, make sure that reloadData is not called while collection view is updating with animation (insert, delete, update or performBatchUpdates).

在我的情况下,设置 collectionView.prefetchingEnabled = NO;解决了我的问题。 只能在 iOS10上运行。

对我来说,我通过自动布局更新了 self. view (CollectionView 的 superview)的高度,然后必须调用 layoutIfNeeded

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

Just resolved this issue, for a somewhat specific situation.

在我的例子中,我在父 ViewController 中手动初始化 UICollectionViewController,然后将 UICollectionViewController 的视图添加为子视图。

I resolved the issue by calling 'setNeedsLayout' and/or 'setNeedsDisplay' on the collectionView in the parent's viewDidAppear:

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

My issue was that I had 2 collection views within the same view, and both were sharing a computed UICollectionViewFlowLayout instance. Once I created separate instances of the same flow layout, it worked fine.

在使用 UICollectionViewDelegateFlowLayout时,要注意这个函数返回的内容。widthheight都应大于 0。我使用 window作为帧参考,但由于复杂的视图层次结构窗口在运行时是 nil。如果需要根据屏幕宽度调整元素的宽度,请使用 UIScreen.main.bounds

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

它可能是实际的布局问题。检查布局警告从控制台,如果存在。

我使用的是自动布局,在我的案例中是 缺少高度约束

In my case the collection view was not fully visible in its parent view due to wrong auto layout constraints. So fixing the constraints made the collection view all visible and cellForItemAtIndexPath was called.

在情节串连板/xib UICollectionView 属性 cellSize 不能是{0,0}

在我的情况下,我必须调整估计的内容大小。内容大小没有做到这一点。

  let layout = collectionVC.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: 100, height: 100)
layout.estimatedItemSize = CGSize(width: 100, height: 100)

我也遇到过类似的问题。但是,当项目数大于1时调用 cellForItemAtIndexPath,而不是当只有一个项目时调用 cellForItemAtIndexPath。我在这里尝试了许多建议的解决方案,并且与我发现的许多解决方案类似,都与项目大小有关。对我来说,解决方案是将 UICollectionView的估计大小从 自动的改为 习俗

Set estimate size to Custom

在我的情况下,我有 collectionViewUIStackViewalignment = .center。所以 collectionView没有宽度。将 stackView.alignment设置为 .fill时,一切正常。

在我的案例中,我找到了这样的解决办法:

  //IF RELOAD COLLECTION VIEW AFTER DELAY IT WORKS
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
//ASSIGN NEW DATA SOURCE
self.arrItem = arrModel
self.collectionView.reloadData()
}

I)请确保将 UICollectionView 添加到 UITableViewCell ContentView不是以 subView 的形式

reloadSections而不是 reloadData为我做到了。

I don't know why reloadData did not work.

以下是我的观察结果:

如果 UICollectionViewDelegateFlowLayout< strong > sizeForItemAt 方法返回0 size,则 < em > < strong > cellForItemAt will not call.

因此不会显示集合视图。