Ios UICollectionView和辅助视图(标题)

Ios UICollectionView和辅助视图(标题),ios,objective-c,uicollectionview,uicollectionviewlayout,Ios,Objective C,Uicollectionview,Uicollectionviewlayout,正在尝试将补充视图作为标题添加到myUICollectionView中。我在工作中遇到了问题 我使用自定义的UICollectionViewFlowLayout返回一个总是比帧大至少1像素的contentSize(我使用的是UIFreshControl,它只有在UICollectionView滚动并且设置collectionView.contentSize直接不起作用时才起作用)要在部分插入和项目大小更改中使项目无效,请执行以下操作: -(void)setSectionInset:(UIEdge

正在尝试将补充视图作为标题添加到my
UICollectionView
中。我在工作中遇到了问题

我使用自定义的
UICollectionViewFlowLayout
返回一个总是比帧大至少1像素的
contentSize
(我使用的是
UIFreshControl
,它只有在
UICollectionView
滚动并且设置
collectionView.contentSize
直接不起作用时才起作用)要在
部分插入
项目大小
更改中使项目无效,请执行以下操作:

-(void)setSectionInset:(UIEdgeInsets)sectionInset {
    if (UIEdgeInsetsEqualToEdgeInsets(super.sectionInset, sectionInset)) {
        return;
    }

    super.sectionInset = sectionInset;

    [self invalidateLayout];

}

-(void) setItemSize:(CGSize)itemSize {
    if (CGSizeEqualToSize(super.itemSize, itemSize)) {
        return;
    }

    super.itemSize = itemSize;

    [self invalidateLayout];
}

- (CGSize)collectionViewContentSize
{
    CGFloat height = [super collectionViewContentSize].height;

    // Always returns a contentSize larger then frame so it can scroll and UIRefreshControl will work
    if (height < self.collectionView.bounds.size.height) {
        height = self.collectionView.bounds.size.height + 1;
    }

    return CGSizeMake([super collectionViewContentSize].width, height);
}
尝试实施它:

DatasetLayout *collectionViewFlowLayout = [[DatasetLayout alloc] init];
collectionViewFlowLayout.itemSize = CGSizeMake(360, 160);
collectionViewFlowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
collectionViewFlowLayout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16);
collectionViewFlowLayout.minimumInteritemSpacing = 16;
collectionViewFlowLayout.minimumLineSpacing = 16;
collectionViewFlowLayout.headerReferenceSize = CGSizeMake(0, 100);

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewFlowLayout];
collectionView.translatesAutoresizingMaskIntoConstraints = FALSE;
collectionView.backgroundColor = [UIColor yellowColor];
collectionView.delegate = self;
collectionView.dataSource = self;
我注册班级:

[self.collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];
并执行以下任务:

-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {

    CollectionHeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView" forIndexPath:indexPath];

    headerView.headerLabel.text = @"Blarg!";

    return headerView;
}
线路

collectionViewFlowLayout.headerReferenceSize = CGSizeMake(0, 100);
导致错误的原因:

*** Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:], /SourceCache/UIKit_Sim/UIKit-2380.17/UICollectionView.m:1150
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView dataSource is not set'
如果我把它注释掉,它会运行,但没有标题


我做错了什么或没有实现什么?

如果您查看错误消息,它表示未设置数据源。这应该可以解决这个问题:

self.collectionView.dataSource=self

确保视图控制器实现数据源协议:


YourViewController:UIViewController

我清理了我的代码,删除了我在IB中创建的UICollectionView,并在代码中创建了它。我再次运行了it,得到了一个不同的错误,并意识到我没有在IB中设置委托或数据源。我做到了:

self.collectionView.delegate = self;
self.collectionView.datasource = self;
但这肯定不够好

因此,使用在IB中创建的UICollectionView,而不是在IB中设置delgate/datasource,而是在代码中:

[self.view bringSubviewToFront:self.collectionView];
self.collectionView.collectionViewLayout = collectionViewFlowLayout;
self.collectionView.backgroundColor = [UIColor orangeColor];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;

[self.collectionView registerClass:[DatasetCell class] forCellWithReuseIdentifier:@"cvCell"];

[self.collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];
这是一个问题。我重新编辑了它以创建UICollectionView all-in代码:

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewFlowLayout];
collectionView.translatesAutoresizingMaskIntoConstraints = FALSE;
collectionView.backgroundColor = [UIColor yellowColor];
collectionView.delegate = self;
collectionView.dataSource = self;

[collectionView registerClass:[DatasetCell class] forCellWithReuseIdentifier:@"cvCell"];

[collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];

[self.view addSubview:collectionView];

self.collectionView = collectionView;
我得到了一个不同的错误:

*** Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2380.17/UICollectionView.m:2249
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindSectionHeader with identifier CollectionHeaderView - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
我会努力弄清楚的

编辑:

我发现,我注册的标题不正确:

[collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];
切换到:

UINib *headerNib = [UINib nibWithNibName:@"CollectionHeaderView" bundle:nil];

[collectionView registerNib:headerNib forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];

一切正常。不完全确定注册表类:
是如何工作的。

我遇到了类似的问题,但我的应用程序在以编程方式弹出UICollectionViewController后崩溃。出于某种原因(我认为这只是SDK中的一个bug),self.collectionView在其“控制器销毁”后仍处于活动状态,因此导致此故障:

*** Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:applyAttributes:], /SourceCache/UIKit/UIKit-2935.137/UICollectionView.m:1305
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView dataSource is not set'
解决方案只是在UICollectionViewController中覆盖-dealloc并手动释放self.collectionView。ARC代码:

- (void)dealloc {

    self.collectionView = nil;
}

希望这能为某人节省时间。

我还遇到了一个恼人的错误:

*** Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:applyAttributes:], /SourceCache/UIKit/UIKit-3347.44/UICollectionView.m:1400
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView dataSource is not set'
我发现有些人通过这样做来解决这个错误

- (void)dealloc {
    self.collectionView = nil;
}
或使用swift:

deinit {
    collectionView = nil
}
然而,这两个问题都没有解决我的崩溃。 我尝试了一些方法,以下“黑客”解决了这个恼人的错误:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    if collectionView.dataSource != nil {
        return someHeaderSize
    } else {
        return CGSizeZero
    }
}

我遇到了同样的问题,同样,我没有正确注册标题。这里有几个线程都建议使用Nib来定义头,但我做的不同,效果很好

我有一个自定义头SizeCollectionHeader,它继承了UICollectionReusableView。它是这样注册的

    [self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"UICollectionElementKindSectionHeader"
                                                                             withReuseIdentifier:@"SupplementaryViewIdentifier"];
    [self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"SupplementaryViewKind"
                                                                             withReuseIdentifier:@"SupplementaryViewIdentifier"];
而且工作正常

我最初的问题是它有这样一个随机的“种类”值

    [self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"UICollectionElementKindSectionHeader"
                                                                             withReuseIdentifier:@"SupplementaryViewIdentifier"];
    [self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"SupplementaryViewKind"
                                                                             withReuseIdentifier:@"SupplementaryViewIdentifier"];
这会崩溃


因此,我只想对正在查看此主题的任何人说,您不需要使用笔尖。

本主题中的答案非常陈旧,在iOS8和iOS9中不起作用。如果您仍然存在上述问题,请查看以下主题:

编辑

如果链接无效,答案如下:

如果在集合视图中使用自定义布局,请检查其数据源是否为零:

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
结果应该如下所示:

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    if (self.collectionView.dataSource != nil) {
        // Your layout code    
        return array;
    }
    return nil;
}
此更改解决了以下问题:

  • -[UICollectionView\u createPreparedSupplementaryViewForElementOfKind:atIndexPath:WithLayoutAttribute:applyAttributes:]中的断言失败
您也可以检查以下主题,但在我的案例中,它没有解决任何问题:

希望它能帮助你,你不会像我那样浪费时间。

试试这个:

self.collectionView?.dataSource = nil
self.collectionView = nil

它对我有用;)

这个答案与其他方法类似,后者创建了一个检查数据源的方法,但它稍微简单一点。这个问题似乎与集合发布后集合视图的布局有关。因此,我将布局的属性归零,如下所示,错误消失了

deinit {
    let layout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
    layout.estimatedItemSize = CGSizeZero
    layout.sectionInset = UIEdgeInsetsZero
    layout.headerReferenceSize = CGSizeZero
}

我总是犯同样的错误。我已经为我的collectionView设置了CustomHeaderView。我将集合可重用视图的类设置为CustomHeaderView,并设置了标识符。我花了1/2个小时试图弄明白为什么这会失败

由于未捕获异常而终止应用程序 “NSInternalInconsistencyException”,原因:“无法将视图出列。” 种类:带标识符的UICollectionElementKindSectionFooter SectionHeader-必须为标识符或类注册nib或类 连接故事板中的原型单元

你需要仔细阅读日志…吸取教训

'无法将视图出列 种类:UICollectionElementKindSectionFooter


原因是因为在故事板中-在collectionView标识检查器中,我检查了两个附件:节页眉和节页脚。我只需要部分标题。只需取消选中页脚…构建并运行…轰

一个iOS9错误,在viewcontroller的dealloc集合层委托nil中

- (void)dealloc{

    if ([[[UIDevice currentDevice] systemVersion] hasPrefix:@"9"]) {
        self.collectionView.layer.delegate = nil;
    }
}

错误抱怨“未设置UICollectionView数据源”。–collectionView:ViewForSupplementElementOfKind:atIndexPath:实际上是一个数据源协议方法,而不是委托协议方法。您有集合视图集的dataSource属性吗?我不太清楚您所说的“集合视图集的dataSource属性”是什么意思?我有一个数据源,如果我不尝试执行标头,则会显示该数据源。UICollectionView对象具有数据源属性。您得到的错误是,您没有将其设置为将实现–collectionView:ViewForSupplementalElementOfKind:atIndexPath:Method的对象。您所说的是
集合吗