试图AA补充视图加入到我的UICollectionView
作为标题。 我在得到它的工作的问题。
我使用自定义UICollectionViewFlowLayout
返回一个contentSize
,始终是至少1个像素较大,则帧(我使用的是UIFreshControl
这只会如果工作UICollectionView
卷轴,并设置collectionView.contentSize
直接什么都不做)和invalidateLayout
上sectionInsert
和itemSize
变化:
-(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);
}
我创建了一个UICollectionReusableView
类这仅仅是一个UIView
用UILabel
:
@implementation CollectionHeaderView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"CollectionHeaderView" owner:self options:nil];
if ([arrayOfViews count] < 1) {
return nil;
}
if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
return nil;
}
self = [arrayOfViews objectAtIndex:0];
self.headerLabel.text = @"This is a header. There are many like it.";
self.backgroundColor = [UIColor yellowColor];
}
return self;
}
努力实现它:
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'
如果我注释掉,它运行但没有头。
我在做什么错误或不执行?
Answer 1:
我面临着类似的问题,但我的应用程序崩溃后,我以编程方式弹出我的UICollectionViewController。 在某种原因(我认为这只是在SDK中的错误)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'
该解决方案只是替代-dealloc在UICollectionViewController和手动释放self.collectionView。 ARC的代码:
- (void)dealloc {
self.collectionView = nil;
}
希望这将节省时间的人。
Answer 2:
本主题中的答案是很老,而且没有在iOS8上和iOS9工作。 如果您仍然有描述问题,请查看以下主题: UICollectionView和补充视图崩溃
编辑 :
下面是答案,万一链路失效:
如果您在您的收藏视图中使用自定义布局,检查其数据源是零:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
结果应该是这个样子:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
if (self.collectionView.dataSource != nil) {
// Your layout code
return array;
}
return nil;
}
这种变化解决了以下问题:
- 断言失败 - [UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:applyAttributes:]
您还可以查看下面的主题,但它并没有解决我的情况下,任何东西:
移除空的空间中,如果报头部分被隐藏在UICollectionView
希望它会帮助你,你不会浪费我一样多的时间。
Answer 3:
我清理我的代码并删除我在IB创建的UICollectionView和创造这一切的代码。 我又跑了,并得到一个不同的错误,并意识到我没有设置委托或数据源中的IB。 我所做的:
self.collectionView.delegate = self;
self.collectionView.datasource = self;
但是,绝不能一直不够好。
因此,与UICollectionView在IB,而不是设置在IB的delgate /数据源,而是在代码中创建:
[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:
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"];
和一切正常。 不完全知道怎么registerClass:
没有,虽然工作。
Answer 4:
如果你看一下错误信息,上面说的数据源未设置。 这应该可以解决它:
self.collectionView.dataSource = self;
请确保您的视图控制器实现了数据源的协议:
YourViewController : UIViewController<UICollectionViewDataSource>
Answer 5:
我也有这个恼人的错误:
*** 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
}
}
Answer 6:
这个答案是相似的,你创建检查数据源的方法的人,但它是一个有点简单。 看来这个问题是关系到集合释放后集合视图的布局坚持围绕。 所以我下面清零布局的属性和错误消失。
deinit {
let layout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.estimatedItemSize = CGSizeZero
layout.sectionInset = UIEdgeInsetsZero
layout.headerReferenceSize = CGSizeZero
}
Answer 7:
我有同样的问题,同样,我是不是正确登记的标题。 这里对于多个线程,所有建议使用笔尖来定义头,但我做不同的,并工作正常。
我有一个自定义标题SizeCollectionHeader,它继承了UICollectionReusableView。 据注册这样的。
[self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"UICollectionElementKindSectionHeader"
withReuseIdentifier:@"SupplementaryViewIdentifier"];
并且工作正常。
我最初的问题是,有这样一个随机的“有心人”的价值。
[self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"SupplementaryViewKind"
withReuseIdentifier:@"SupplementaryViewIdentifier"];
这将崩溃。
所以,我只是想为正在这里,你不需要用笔尖任何人发表评论。
Answer 8:
试试这个 :
self.collectionView?.dataSource = nil
self.collectionView = nil
它的工作对我来说)
Answer 9:
我一直得到了同样的错误。 我已经建立了我的CollectionView的CustomHeaderView。 我有类集合可重复使用的视图的我CustomHeaderView,我不得不设置标识符。 我半小时试图找出为什么这个是失败。
终止应用程序由于未捕获的异常“NSInternalInconsistencyException”,理由是:“不能出列类型的视图:UICollectionElementKindSectionFooter与标识符SectionHeader - 必须注册标识的笔尖或类或故事板连接原型细胞”
你需要仔细阅读日志...教训。
“不能出列类型的视图:UICollectionElementKindSectionFooter
究其原因是因为在故事板 - 中的CollectionView身份督察检查了两个附件:节头和页脚节。 我只需要一节头。 只要取消躯......建立和run..BOOM!
Answer 10:
一个iOS9错误,在视图控制器的dealloc的集层委托为零。
- (void)dealloc{
if ([[[UIDevice currentDevice] systemVersion] hasPrefix:@"9"]) {
self.collectionView.layer.delegate = nil;
}
}
文章来源: UICollectionView and Supplementary View (header)