iOS中UICollectionView出现断言失败

29

我遇到了一个错误...

*** Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:], /SourceCache/UIKit/UIKit-2372/UICollectionView.m:2249

当试图显示一个UICollectionView时。

引起问题的代码行是...

static NSString *CellIdentifier = @"Cell";

UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];

出现了出队列错误。

由于没有其他错误,我不知道从哪里开始解决。

是否有人可以阐述一下?

7个回答

37

您需要像以下这样进行注册:

[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"MY_CELL"];

29

我一直在阅读文档(可能应该先这样做🙂)。

无论如何,我正在使用一个在单独的xib文件中的collectionView(不是故事板),从文档中得知...

Important: You must register a class or nib file using the
registerClass:forCellWithReuseIdentifier: or
registerNib:forCellWithReuseIdentifier: method before calling this method.
感谢。

你什么时候调用这个方法?是在“UICollectionViewCell *cell = [collectionView dequeue...”这一行的前面还是在另一个方法中? - Jordan Medlock
1
我必须在viewDidLoad方法中进行注册。你只需要为整个collectionView注册一次xib。然后,当你调用dequeueCellWithIdentifier时,它会去到你注册的xib。 - Fogmeister
2
我也遇到了同样的问题,但出于某种奇怪的原因,编译器无法在viewDidLoad方法中识别registerClass方法,所以我不得不将其移动到cellForItemAtIndexPath方法中。 - Sam Spencer
@Sam:这可能是因为在viewDidLoad中调用registerClass:forCellWithReuseIdentifier:方法时,您的UICollectionView对象尚未分配。如果您的集合视图是通过Interface Builder定义的,则不应发生这种情况,因为viewDidLoad在初始化集合视图后调用。如果您以编程方式初始化集合视图,请确保在调用registerClass:...方法之前对其进行分配。我认为cellForItemAtIndexPath不是最好的地方... - CGee
1
谢谢!你节省了我的时间 :) - Oleg Popov
@Sam 我曾经遇到过同样的问题,原因是 cellForItemAtIndexPath[super viewDidLoad] 中被调用,当我将 registerNib:... 移动到 [super viewDidLoad] 之前时,它就正常工作了。 - Zuzana Paulis

4

我曾经遇到过同样的问题,以下是我解决它的方法。

[self.pictureCollectionView registerNib:[UINib nibWithNibName: bundle:nil] forCellWithReuseIdentifier:reuseID]

移动到- (void)viewDidLoad方法中,而不是- (void)awakeFromNib方法中。


3

确保如果您使用registerNib:方法:

UINib *nibH = [UINib nibWithNibName:HEADER_ID bundle:nil];
[collectionView registerNib:nibH
 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader 
        withReuseIdentifier:HEADER_ID];

此外,在 nib 文件中,当您选择顶级集合可重用视图时,请使用属性检查器,并确保 Identifier 属性设置为与传递给 withReuseIdentifier: 参数相同的值。


1
我收到了这个问题,只有在iOS 9上崩溃(iOS 10/11正常工作)。
我没有自定义Flow Layout的子类,而是直接在现有的Layout上设置headerReferenceSize。 所以在Interface Builder中启用“Section Header”后,我遇到了这个崩溃,但是如果不勾选,一切都正常工作,头部将正确显示,因为我在代码中设置了大小。

enter image description here


也许现在很少有应用支持iOS 9了 :D。但很高兴它有帮助到你! - heyfrank

0

当使用多个具有唯一重用标识符的UICollectionView时,我曾经看到过这个错误弹出。在ViewDidLoad中,您需要像这样注册每个CollectionView的重用标识符:

[_collectionView1 registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"collectionView1CellIdentifier"];
[_collectionView2 registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"collectionView2CellIdentifier"];

当你到达"- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath"时,你要确保不要将collectionView1的单元格设置为collectionView2的重用标识符,否则会出现错误。 不要这样做:(或者collectionView2在看到它期望的标识符之前,会看到错误的标识符并抛出异常)
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"collectionView1CellIdentifier" forIndexPath:indexPath];

if(collectionView != _collectionView1){
   cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"collectionView2CellIdentifier" forIndexPath:indexPath];
}

cell.backgroundColor = [UIColor greenColor];
return cell;

做这个:

UICollectionViewCell *cell;

if(collectionView == _collectionView1){
    cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"collectionView1CellIdentifier" forIndexPath:indexPath];
}else{
   cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"collectionView2CellIdentifier" forIndexPath:indexPath];
}

cell.backgroundColor = [UIColor greenColor];
return cell;

0

替换

NSString *CellIdentifier = @"Cell";

使用

static NSString *CellIdentifier = @"Cell";

我先尝试了那个。我只是在阅读文档。在运行dequeue之前,我需要注册一个类或nib... - Fogmeister

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接