未调用UICollectionView的cellForItemAtIndexPath

Ike*_*aro 95 objective-c ios uicollectionview

只有我第二次使用UICollectionView,也许我已经咬过的东西超过了我可以咀嚼但是:

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

包含myCollectionView的子类UICollectionViewController正被推送到导航控制器堆栈.目前,myCollectionView loas和水平滚动已启用.但是,没有细胞可见.我已经证实了这一点

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
Run Code Online (Sandbox Code Playgroud)

已运行并返回一个大于0的整数.我还确认myCollectionView的委托和数据源在IB中正确设置为子类UICollectionViewController.

要加载单元格的方法:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
Run Code Online (Sandbox Code Playgroud)

没有被召唤.

这是我在该控制器中推送UICollectionViewController和viewDidLoad方法的地方(注意:initWithBill是普通初始化程序的覆盖):

在之前的ViewControllers .m文件中:

FullReceiptViewController *test = [[FullReceiptViewController alloc] initWithBill:currentBill];
test.title = @"Review";
[self.navigationController pushViewController:test animated:YES];
Run Code Online (Sandbox Code Playgroud)

在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];
Run Code Online (Sandbox Code Playgroud)

有关为什么不被调用的任何线索?

Ike*_*aro 126

对于那些后来绊倒的人......原因是:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
Run Code Online (Sandbox Code Playgroud)

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

[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];
Run Code Online (Sandbox Code Playgroud)

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

  • 如果你使用autolayout - 一定要在collectionView上设置一个高度约束 - 浪费了很多时间! (46认同)
  • 如果你的collectionView被AutoLayout约束到topLayoutGuide,并且不应该在NavigationBar下滚动,请确保在Storyboard上的ViewController上取消选中`Adjust Scroll View Insets`. (4认同)

esi*_*ver 89

在我的情况下,这是因为我的布局类错误地子类UICollectionViewLayout而不是UICollectionViewFlowLayout


Dee*_*G M 26

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

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

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

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

  • 例如,要使用完整的可用大小,请从collectionViewContentSize返回collectionView.frame.size(不仅仅是默认为0, 0的collectionView.contentSize) (2认同)
  • 谢谢。在我的例子中,“collectionViewContentSize”错误地返回了 0 宽度,这就是为什么“cellForItemAtIndexPath”没有被调用。 (2认同)

Ant*_*lli 15

也许我只是忽略它,但似乎你错过了你的代表和数据源.在头文件中,请确保添加了以下内容:

<UICollectionViewDelegate, UICollectionViewDataSource>
Run Code Online (Sandbox Code Playgroud)

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

self.myCollectionView.delegate = self;
self.myCollectionView.dataSource = self;
Run Code Online (Sandbox Code Playgroud)

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


Jay*_*ybo 15

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

self.automaticallyAdjustsScrollViewInsets = NO;
Run Code Online (Sandbox Code Playgroud)


Gur*_*ngh 13

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

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

    collectionView?.setCollectionViewLayout(layout, animated: false)
Run Code Online (Sandbox Code Playgroud)


Aam*_*irR 8

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


Wou*_*ter 7

我也有类似的问题。但当cellForItemAtIndexPath项目数 > 1 时被调用,但只有一个项目时则不会被调用。我在这里尝试了许多建议的解决方案,与许多类似,我发现它与项目尺寸有关。对我来说,解决方案是将估计大小UICollectionView“自动”更改为“自定义”

将估计尺寸设置为自定义


小智 6

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


Nic*_* S. 6

就我而言,我有collectionView一个UIStackViewwith alignment = .center。所以collectionView没有宽度。当设置为stackView.alignment一切.fill都很好。


小智 5

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


小智 5

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

collectionView.translatesAutoresizingMaskIntoConstraints = false
Run Code Online (Sandbox Code Playgroud)


sas*_*nec 5

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


6da*_*id9 5

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

  • 我前段时间对这个答案投了赞成票,今天它再次帮助了我:D 你应该因为这个答案而获得诺贝尔奖。再次感谢! (2认同)