116

只有我第二次使用 UICollectionView's,也许我已经咬得比我能咀嚼的还多,但尽管如此:

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

包含 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];

关于为什么不调用它的任何线索?

4

33 回答 33

146

对于那些后来在这里绊倒的人......原因:

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

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

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

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

于 2013-02-04T07:17:14.040 回答
106

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

于 2014-08-20T22:32:22.863 回答
35

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

  1. 如果您使用的是 Flow 布局:您需要正确设置项目大小。
  2. 如果您有从 UICollectionViewLayout 子类化的自定义布局:确保从 collectionViewContentSize 方法返回正确的大小。

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

因此,只需覆盖 collectionViewContentSize 并在那里提供适当的大小,它应该可以解决您的问题。

于 2014-07-22T09:59:22.597 回答
18

有关更复杂的视图层次结构,请查看此博客。它救了我的命!

self.automaticallyAdjustsScrollViewInsets = NO;
于 2016-01-08T08:34:59.010 回答
16

也许我只是忽略了它,但您似乎缺少您的委托和数据源。在你的头文件中,确保你已经添加了这些:

<UICollectionViewDelegate, UICollectionViewDataSource>

并在您的 viewDidLoad 方法中添加:

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

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

于 2013-02-03T02:20:11.517 回答
15

如果您的类是 UICollectionviewController 的子类,并且您正在以编程方式创建 collectionView,则使用

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

    collectionView?.setCollectionViewLayout(layout, animated: false)
于 2017-01-30T14:56:23.770 回答
10

我正在使用自动布局,在我的情况下缺少高度约束

于 2017-11-27T11:20:13.070 回答
6

就我而言,我非常愚蠢地忘记做的是实现UICollectionViewDataSource协议方法numberOfItemsInSection,所以这是另一件要检查的事情。

于 2014-02-05T07:41:54.173 回答
6

我的问题是我在同一个视图中有 2 个集合视图,并且两者都共享一个计算UICollectionViewFlowLayout实例。一旦我创建了相同流布局的单独实例,它就可以正常工作。

于 2017-09-07T17:52:24.850 回答
5

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

我的意图是使用 UICollectionViewFlowLayout,

但是因为出错,我使用了UICollectionViewLayout。

于 2015-04-18T08:01:49.107 回答
5

此外,请确保在集合视图使用动画更新(插入、删除、更新或 performBatchUpdates)时不调用 reloadData。

于 2017-05-17T00:30:34.423 回答
4

在我的情况下,我有collectionView一个UIStackViewwith alignment = .center。所以collectionView没有宽度。当设置stackView.alignment.fill一切都很好。

于 2020-05-04T16:01:34.410 回答
4

就我而言, setcollectionView.prefetchingEnabled = NO;解决了我的问题。仅适用于 iOS 10。

于 2017-05-19T02:25:53.047 回答
4

我遇到了类似的问题。但是cellForItemAtIndexPath当项目数> 1时调用,而不是当只有一个项目时调用。我在这里尝试了许多建议的解决方案,并且与许多我发现它与项目大小有关的解决方案类似。对我来说,解决方案是将估计大小UICollectionViewAutomatic更改为Custom

将估计大小设置为自定义

于 2020-04-18T06:42:15.323 回答
3

当通过修复调用 cellForItem 方法来修复 item height == 0 时,我正在发生这种情况。

于 2013-11-20T13:36:09.417 回答
3

在 storyboard/xib UICollectionView 属性 cellSize 不能是 {0, 0}

于 2018-10-10T14:43:47.450 回答
3

在 Xcode 7.0.1 中,当我们从另一个项目复制故事板和随附代码时,我们遇到了这个问题。集合视图在情节提要中设置了自定义流程布局。解决方案是:

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

现在它起作用了:)

于 2015-10-29T07:15:19.157 回答
3

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

collectionView.translatesAutoresizingMaskIntoConstraints = false
于 2016-03-02T18:58:20.960 回答
3

就我而言,将 UINavigationBar 的半透明更改为 NO 解决了这个问题。

于 2015-09-02T08:03:42.690 回答
2

确保 -(NSInteger) collectionView:numberOfItemsInSection: 返回一个正值(读取,大于零)。可能是放置 [self.collectionView reloadData]; 在完成处理程序中。

于 2015-01-30T21:48:35.790 回答
2

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

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

于 2015-01-13T18:51:21.077 回答
2

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

于 2017-11-01T09:52:14.020 回答
2

在我的情况下,由于错误的自动布局约束,集合视图在其父视图中不完全可见。因此,修复约束使集合视图全部可见,并且调用了 cellForItemAtIndexPath。

于 2017-12-06T10:21:18.360 回答
2

如果您使用集合视图协议,则必须将CollectionViewDataSourceCollectionViewDelegate协议连接到您的 ViewController。 界面构建器出口

于 2017-03-28T11:40:57.677 回答
2

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

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: 
           UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {}
于 2017-10-19T09:50:13.083 回答
1

我也发生了同样的事情。我有 2 个 UICollectionViews,我删除了一次,因为我不需要它。之后,我意识到 CellForItemAtIndexPath 没有被调用,而是其他必需的方法。我尝试了以上所有方法,但后来我做了标准的魔术。从情节提要中删除了集合视图并再次添加。然后它开始工作。不知道为什么,我没有解释,但可能是一些连接问题。

于 2014-11-01T03:35:58.173 回答
1

对我来说,我通过自动布局更新 self.view(collectionView 的超级视图)的高度,然后必须调用layoutIfNeeded

[self.view mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.equalTo(@(height));
}];
[self.view layoutIfNeeded];
于 2017-06-13T13:42:39.607 回答
1

Just resolved this issue, for a somewhat specific situation.

In my case, I was manually initializing the UICollectionViewController in a parent ViewController, and then adding the UICollectionViewController's view as a subview.

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];
}
于 2017-07-16T00:34:49.463 回答
0

就我而言,我不得不调整估计的内容大小。内容大小没有做到这一点。

  let layout = collectionVC.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
    layout.itemSize = CGSize(width: 100, height: 100)
    layout.estimatedItemSize = CGSize(width: 100, height: 100)
于 2019-12-19T09:22:04.807 回答
0

就我而言,我找到了解决方法:

  //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()
    }
于 2021-06-10T08:19:38.867 回答
0

i) 请确保将 UICollectionView 添加到 UITableViewCells contentView不是 subView

于 2021-12-22T22:58:16.423 回答
-1

在从情节提要加载的包含视图控制器中使用 CollectionView 时,我花了一些时间来解决这个问题。我最终只是删除了包含的视图控制器,并在情节提要中重新创建它,这似乎解决了这个问题。我的猜测是发生了某种情节提要损坏。

于 2016-01-20T00:34:51.287 回答
-2

在自定义单元格的 layoutSubViews() 中设置 collectionView 框架对我有用:

override func layoutSubviews() {
        super.layoutSubviews()
        let frame = self.contentView.bounds
        self.CollectionView.frame = frame
    }
于 2015-12-25T11:42:47.487 回答