11

Ich habe eine UICollectionView mit einem benutzerdefinierten Layout umgesetzt. Es fügt dem Layout eine Dekorationsansicht hinzu. Ich verwende den folgenden Code-Layout-Attribute des Dekors Ansicht hinzuzufügen:UICollectionView Dekoration in leerer Sammlung Ansicht

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 
{ 
    NSArray *allAttributes = [super layoutAttributesForElementsInRect:rect]; 
    return [allAttributes arrayByAddingObject:[self layoutAttributesForDecorationViewOfKind:kHeaderKind atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]]; 
} 

Die Daten in der Sammlung Ansicht wird durch eine NSFetchedResultsController vorgesehen.

Jetzt sah es mag es funktioniert gut, aber wenn die Sammlung Ansicht leer ist, schlägt fehl, weil es Abschnitt ist 0. Versuchte es ohne Index-Pfad zu verwenden, aber auch fehlschlägt. Irgendwelche Gedanken darüber, wie man Dekorationsansichten in einer leeren UICollectionView verwendet? Dies sollte möglich sein, da Dekorationsansichten nicht datengesteuert sind.

+1

Hallo, haben Sie dieses Problem gelöst, bitte aktualisieren Sie Ihre Antwort, so dass wir auch etwas Hilfe bekommen können. –

+0

Können Sie bitte etwas mehr Code, so dass ich das Problem leicht reproduzieren kann –

+1

Erhalten Sie die gleiche Fehlermeldung in beiden Fällen? Weil es für mich funktioniert, wenn ich "Null" als Indexpfad verwende (Xcode 5.1.1, iOS SDK 7.1 Simulator). Wenn es stattdessen unbemerkt fehlschlägt, gibt der Aufruf 'super' möglicherweise 'nil' zurück (Standardwert 'UICollectionViewLayout')? –

Antwort

0

I erstellt und getestet dieses einfache Beispiel, das in iOS 7 in allen möglichen Situationen (0 Abschnitte, 1 Abschnitt mit 0 Produkten usw.) scheint zu funktionieren. Dies ist meine Layout-Klasse, Unterklasse UICollectionViewFlowLayout. Der Rest des Projekts ist nur Gerüste.

#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

Nicht sicher, ob die Verwendung von 'nil' als Indexpfad die Dinge geändert hat, aber mit dem obigen Code funktioniert es in der Tat perfekt. Es ist auch möglich, dass es damals nicht funktioniert hat, 'UICollectionView's waren damals irgendwie fehlerhaft. –

+0

Ja, wahrscheinlich eine Kombination aller oben genannten. Die Dokumentation bietet nicht viele Hinweise zur Behandlung von NSIndexPath für Dekorationsansichten, außer zu sagen: "Es liegt an Ihnen zu entscheiden, wie der IndexPath-Parameter zum Identifizieren einer bestimmten Dekorationsansicht verwendet wird". – Jaanus

+1

Leider funktioniert das nicht mehr seit 'layoutAttributesForDecorationViewOfKind: indexPath:' erwartet einen 'nonnull' Indexpfad. – ianolito

4

Wenn zu einer bestimmten Zelle einer Dekoration Ansicht oder eine Ergänzungsansicht nicht angebracht mit [NSIndexPath indexPathWithIndex:] verwenden Sie den Index Pfad angeben. Hier ist ein Beispielcode:

@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

Ja, die Verwendung von NSIndexPath, das nicht auf Abschnitten/Elementen basiert, scheint zu funktionieren. Das macht mich allerdings ein bisschen unbehaglich - ich denke, dass die meisten dieser APIs davon ausgehen, dass der indexPath dem Format section.item entspricht, obwohl diese spezifische Verwendung keine negativen Auswirkungen zu haben scheint. – Jaanus

+0

@Jaanus Wenn Null ein akzeptabler Wert ist, denke ich, dass es in der Dokumentation erwähnt würde. Es ist normal, keinen Indexpfad mit einem Abschnitt + Element zu erstellen, da der Indexpfad nicht an ein bestimmtes Element gebunden ist. – Benoit