Cocoa touch UICollectionView在空集合视图中进行装饰
我用自定义布局实现了一个Cocoa touch UICollectionView在空集合视图中进行装饰,cocoa-touch,ios6,nsfetchedresultscontroller,uicollectionview,Cocoa Touch,Ios6,Nsfetchedresultscontroller,Uicollectionview,我用自定义布局实现了一个UICollectionView。它将装饰视图添加到布局中。我使用以下代码添加装饰视图的布局属性: -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray *allAttributes = [super layoutAttributesForElementsInRect:rect]; return [allAttributes arrayByAddingObject:[sel
UICollectionView
。它将装饰视图添加到布局中。我使用以下代码添加装饰视图的布局属性:
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray *allAttributes = [super layoutAttributesForElementsInRect:rect];
return [allAttributes arrayByAddingObject:[self layoutAttributesForDecorationViewOfKind:kHeaderKind atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]];
}
集合视图中的数据由NSFetchedResultsController
提供
现在看起来它工作得很好,但是当集合视图为空时,它失败了,因为存在第0节。尝试在没有索引路径的情况下使用它,但也失败了。关于如何在空的
UICollectionView
中使用装饰视图,您有什么想法吗?应该是可能的,因为装饰视图不是数据驱动的。我创建并测试了这个简单的示例,它似乎在iOS 7中所有可能的情况下都能工作(0个部分,1个部分包含0个项目等)。这是我的布局类,UICollectionViewFlowLayout
的子类。项目的其余部分只是脚手架
#import "JKLayout.h"
#import "JKDecoration.h"
@implementation JKLayout
- (instancetype)init
{
if (self = [super init]) {
[self registerClass:[JKDecoration class] forDecorationViewOfKind:@"Decoration"];
}
return self;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray *allAttributes = [super layoutAttributesForElementsInRect:rect];
// It’s important to set indexPath to nil. If I had set it to indexPath 0-0, it crashed with InternalInconsistencyException
// because I was trying to get decoration view for section 0 while there in reality was no section 0
// I guess if you need to have several decoration views in this case, you’d identify them with a method other than indexpath
return [allAttributes arrayByAddingObject:[self layoutAttributesForDecorationViewOfKind:@"Decoration" atIndexPath:nil]];
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *attr = [super layoutAttributesForDecorationViewOfKind:decorationViewKind atIndexPath:indexPath];
if (!attr) {
attr = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:decorationViewKind withIndexPath:indexPath];
attr.frame = CGRectMake(0, 200, 100, 100);
}
return attr;
}
@end
使用未附加到特定单元格的装饰视图或补充视图时,请使用
[NSIndexPath indexPathWithIndex:
指定索引路径。下面是一个示例代码:
@interface BBCollectionViewLayout : UICollectionViewFlowLayout
@end
@implementation BBCollectionViewLayout
- (void)BBCollectionViewLayout_commonInit {
[self registerClass:[BBCollectionReusableView class] forDecorationViewOfKind:BBCollectionReusableViewKind];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
[self BBCollectionViewLayout_commonInit];
}
return self;
}
- (id)init {
self = [super init];
if (self) {
[self BBCollectionViewLayout_commonInit];
}
return self;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *array = [NSMutableArray arrayWithArray:[super layoutAttributesForElementsInRect:rect]];
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForDecorationViewOfKind:BBCollectionReusableViewKind atIndexPath:[NSIndexPath indexPathWithIndex:0]];
if (CGRectIntersectsRect(rect, attributes.frame)) {
[array addObject:attributes];
}
return array;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:elementKind withIndexPath:indexPath];
attributes.frame = CGRectMake(0., 60., 44., 44.);
return attributes;
}
@end
您好,您已经解决了这个问题,请更新您的答案,以便我们也可以获得一些帮助。您可以发布更多的代码,以便我可以轻松地重现这个问题吗?您在两种情况下都会收到相同的错误消息吗?因为当我使用
nil
作为索引路径(Xcode 5.1.1,iOS SDK 7.1模拟器)时,它对我有效。如果它以静默方式失败,则可能super
调用返回nil
(UICollectionViewLayout
s默认值)?不确定使用nil
作为索引路径是否会改变情况,但使用上面的代码确实可以完美地工作。也有可能当时它不起作用,UICollectionView
s在当时有点问题。是的,可能是以上所有因素的组合。这些文档没有提供关于如何处理装饰视图的nsindepath的太多指导,只是说“由您决定如何使用indepath参数来标识给定的装饰视图”。不幸的是,这不再有效,因为layouttributesfordecorationviewOfkind:indepath:
需要nonnull
索引路径。是的,使用不基于节/项的nsindepath似乎有效。不过,这让我有点不舒服——我认为这些API中的大多数都假设indexPath与section.item格式匹配,尽管这种特定的使用似乎没有任何不良影响。@如果nil是一个可接受的值,我想文档中会提到它。不使用section+项创建索引路径是正常的,因为索引路径未绑定到特定项。