11

我已經實現了具有自定義佈局的UICollectionView。它爲佈局添加了裝飾視圖。我用下面的代碼來添加裝飾視圖的佈局屬性:空集合視圖中的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中使用裝飾視圖的任何想法?由於裝飾視圖不是數據驅動的,因此應該是可能的。

+1

嗨,你有沒有解決這個問題,請更新您的答案,這樣我們也可以得到一些幫助。 –

+0

您可以請張貼更多代碼,以便我可以輕鬆再現問題 –

+1

您是否在兩種情況下都得到相同的錯誤消息?因爲它適用於我使用'nil'作爲索引路徑(Xcode 5.1.1,iOS SDK 7.1 Simulator)。如果它默默地失敗了,也許'super'調用返回'nil'(UICollectionViewLayout的默認值)? –

回答

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 
+1

不確定是否使用'nil'作爲索引路徑改變了事情,但是使用上面的代碼確實可以完美工作。也有可能它沒有工作,那時候'UICollectionView's在那時候有點兒麻煩。 –

+0

是的,可能是以上所有的組合。該文檔不提供有關如何對待NSIndexPath裝飾的看法,不是說「這是由你來決定如何使用indexPath參數來識別一個給定的裝修圖」等多指導。 – Jaanus

+1

不幸的是這不工作了,因爲'layoutAttributesForDecorationViewOfKind:indexPath:'需要一個'nonnull'索引路徑。 – ianolito

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 
+0

是的,使用NSIndexPath不基於部分/項目似乎工作。讓我有點不舒服,雖然,我倒是認爲,大多數這些API-S的假設indexPath的section.item格式相匹配,雖然這具體的使用似乎並沒有什麼不良影響。 – Jaanus

+0

@Jaanus如果nil是可以接受的值,我認爲它會在文檔中提到。由於索引路徑未綁定到特定項目,因此不使用section +項目創建索引路徑是正常的。 – Benoit