未调用UICollectionView的cellForItemAtIndexPath

时间:2013-02-03 02:06:06

标签: ios objective-c uicollectionview

只有我第二次使用UICollectionView并且我可能咬过的东西比我可以咀嚼的还要多但是:

我正在实现一个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];

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

32 个答案:

答案 0 :(得分:119)

对于那些后来偶然发现的人......原因是:

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

没被调用是因为collectionViewFlowLayout的itemSize太高了。

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

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

答案 1 :(得分:77)

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

进行了子类化

答案 2 :(得分:23)

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

  1. 如果您使用的是Flow布局:您需要正确设置项目大小。
  2. 如果您有来自UICollectionViewLayout的自定义布局:确保从collectionViewContentSize方法返回适当的大小。
  3. 如果是后者,您还会发现您的 layoutAttributesForElementsRect 也未被调用。原因是您没有指定内容大小,默认情况下,大小为CGSizeZero。这基本上告诉集合视图,你没有任何内容要绘制,因此它不会向你索要属性或单元格。

    所以,只需覆盖collectionViewContentSize并在那里提供合适的大小,它就可以解决你的问题。

答案 3 :(得分:14)

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

<UICollectionViewDelegate, UICollectionViewDataSource>

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

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

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

答案 4 :(得分:14)

对于更复杂的视图层次结构,请查看此blog。它救了我的命!

self.automaticallyAdjustsScrollViewInsets = NO;

答案 5 :(得分:10)

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

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

    collectionView?.setCollectionViewLayout(layout, animated: false)

答案 6 :(得分:6)

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

答案 7 :(得分:4)

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

答案 8 :(得分:4)

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

答案 9 :(得分:3)

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

我的目的是使用UICollectionViewFlowLayout,

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

答案 10 :(得分:3)

在我的情况下,将UINavigationBar的半透明变为NO解决了这个问题。

答案 11 :(得分:3)

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

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

现在它起作用了:)

答案 12 :(得分:3)

当项目高度== 0时,通过修复调用了cellForItem方法,我发生了这种情况。

答案 13 :(得分:2)

确保numberOfSectionsInCollectionView也返回正整数。

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

答案 14 :(得分:2)

这可能是相关的布局问题。检查控制台的布局警告(如果存在)。

答案 15 :(得分:2)

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

答案 16 :(得分:2)

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

答案 17 :(得分:2)

我忘了在集合视图上将自动调整遮罩设置为false:

collectionView.translatesAutoresizingMaskIntoConstraints = false

答案 18 :(得分:2)

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

答案 19 :(得分:1)

在情节提要/ xib UICollectionView属性中,cellSize不得为{0,0}

答案 20 :(得分:1)

我遇到了类似的问题。但是,当项目数大于1时,将调用cellForItemAtIndexPath,但只有一个项目时,则不会调用UICollectionView。我在这里尝试了许多提议的解决方案,并且与许多我发现它与项目大小有关的方法类似。对我来说,解决方案是将display: inline-block的估算大小从自动更改为自定义

Set estimate size to Custom

答案 21 :(得分:1)

在我的情况下,我将collectionViewUIStackView放在alignment = .center中。因此collectionView没有宽度。将stackView.alignment设置为.fill时,一切都很好。

答案 22 :(得分:1)

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

答案 23 :(得分:1)

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

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

答案 24 :(得分:1)

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

答案 25 :(得分:0)

刚刚针对某种特定情况解决了这个问题。

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

我通过调用&#39; setNeedsLayout&#39;解决了这个问题。和/或&#39; setNeedsDisplay&#39;在父的viewDidAppear:

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

答案 26 :(得分:0)

对我来说,我通过autolayout更新了self.view(collectionView的超级视图)的高度,之后必须调用layoutIfNeeded

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

答案 27 :(得分:0)

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

答案 28 :(得分:0)

就我而言,我必须调整估算的内容大小。内容大小没有做到这一点。

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

答案 29 :(得分: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()
    }

答案 30 :(得分:-1)

我在这个问题上花了一些时间来讨论从故事板加载的Contained视图控制器中的CollectionView。我最终只是删除了包含的视图控制器,并在故事板中重新创建它,这似乎摆脱了这个问题。我的猜测是发生了某种故事板腐败。

答案 31 :(得分:-2)

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

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