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