尝试在我的UICollectionView
中添加补充视图作为标题。我有问题让它发挥作用。
我使用自定义UICollectionViewFlowLayout
返回contentSize
,该UIFreshControl
始终至少比帧大1个像素(我使用UICollectionView
只有{{1}才有效滚动,并设置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'
如果我发表评论,它会运行,但没有标题。
我做错了什么或者没有实施?
答案 0 :(得分:13)
我遇到了类似的问题,但在我以编程方式弹出我的UICollectionViewController后,我的应用程序崩溃了。出于某种原因(我认为它只是SDK中的一个错误)self.collectionView在它的&#39;之后仍然存在。控制器销毁,从而导致这种失败:
*** 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;
}
希望这会为某人节省时间。
答案 1 :(得分:10)
本主题中的答案相当陈旧,并且在iOS8和iOS9中不起作用。如果您仍然遇到上述问题,请查看以下主题:UICollectionView and Supplementary View crash
修改强>:
以下是答案,以防链接失效:
如果您在集合视图中使用自定义布局,请检查其数据源是否为零:
- (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:]
您还可以查看以下主题,但在我的情况下它没有解决任何问题:
Removing empty space, if the section header is hidden in the UICollectionView
希望它会对你有所帮助,你不会浪费我那么多的时间。
答案 2 :(得分:6)
我清理了我的代码并删除了我在IB中创建的UICollectionView并在代码中创建了它。我再次运行它并得到一个不同的错误,并意识到我没有在IB中设置委托或dataSource。我做了:
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:
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:
如何不起作用。
答案 3 :(得分:1)
如果查看错误消息,则表示未设置数据源。这应该解决它:
self.collectionView.dataSource = self;
确保您的视图控制器实现数据源协议:
YourViewController : UIViewController<UICollectionViewDataSource>
答案 4 :(得分:1)
这个答案类似于您创建检查数据源的方法的其他答案,但它更简单一些。似乎问题与收集视图的布局在收集发布后一直存在有关。所以我将布局的属性归零如下,错误消失了。
deinit {
let layout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.estimatedItemSize = CGSizeZero
layout.sectionInset = UIEdgeInsetsZero
layout.headerReferenceSize = CGSizeZero
}
答案 5 :(得分:0)
我也遇到了这个恼人的错误:
*** 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
}
然而这些都没有解决我的崩溃。 我尝试了一些事情以及以下内容&#34; hack&#34;解决了这个烦人的错误:
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
if collectionView.dataSource != nil {
return someHeaderSize
} else {
return CGSizeZero
}
}
答案 6 :(得分:0)
我遇到了同样的问题,同样地,我没有正确地注册标题。这里有几个线程都建议使用Nib来定义标题,但我已经做了不同的工作并且工作正常。
我有一个自定义标头SizeCollectionHeader,它继承了UICollectionReusableView。它是这样注册的。
[self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"UICollectionElementKindSectionHeader"
withReuseIdentifier:@"SupplementaryViewIdentifier"];
并且工作正常。
我最初的问题是有一个随机的&#34;种类&#34;像这样的价值。
[self.collectionView registerClass:[GRSizeCollectionHeader class] forSupplementaryViewOfKind:@"SupplementaryViewKind"
withReuseIdentifier:@"SupplementaryViewIdentifier"];
这会崩溃。
所以我只想评论那些在这里看你不需要使用笔尖的人。
答案 7 :(得分:0)
试试这个:
self.collectionView?.dataSource = nil
self.collectionView = nil
它对我有用;)
答案 8 :(得分:0)
我一直得到同样的错误。我为我的collectionView设置了CustomHeaderView。我有一个Collection Reusable View类到我的CustomHeaderView,我已经设置了标识符。我1/2小时试图弄清楚为什么会失败。
由于未捕获的异常而终止应用 'NSInternalInconsistencyException',原因:'无法使视图出列 种类:带标识符的UICollectionElementKindSectionFooter SectionHeader - 必须为标识符或者注册一个nib或类 连接故事板'
中的原型单元格
您需要仔细阅读日志......吸取教训。
'无法使视图出列 种类:UICollectionElementKindSectionFooter
原因是因为在storyboard中 - 在collectionView Identity Inspector中我检查了两个附件:Section Header和Section Footer。我只需要节标题。简单地取消选中页脚...构建并运行... BOOM!
答案 9 :(得分:0)
iOS9错误,在viewcontroller的dealloc set layer delegate nil。
- (void)dealloc{
if ([[[UIDevice currentDevice] systemVersion] hasPrefix:@"9"]) {
self.collectionView.layer.delegate = nil;
}
}