11

我已经实现了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?应该是可能的,因为装饰视图不是数据驱动的。

4

2 回答 2

4

使用未附加到特定单元格的装饰视图或补充视图时,用于[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
于 2014-07-14T12:45:09.790 回答
0

我创建并测试了这个简单的示例,它似乎在所有可能的情况下都可以在 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
于 2014-07-14T07:39:17.200 回答