2013-04-06 8 views
24

Ich werde ein Bücherregal in einem meiner Projekte erstellen. Die Grundvoraussetzung ist, wie folgt:Erstellen Sie ein Bücherregal mit UICollectionView

  • ähnlich wie iBooks Regal
  • unterstützt beide Orientierungen auch
  • unterstützt alle Arten von IOS-Geräten gut (verschiedene Auflösungen)
  • unterstützt das Löschen und Einfügen von Elementen
  • Abstützungen Neuordnung der Artikel durch langes Drücken Geste
  • zeigt ein verstecktes Logo, wenn die erste Reihe gezogen

Die UICollectionView ist die erste Option, die mir eingefallen ist. Es unterstützt leicht Rasterzellen. So gegoogelt ich es und fand einige sehr nützliche Tutorien:

Bryan Hansen's UICollectionView custom layout tutorial

Mark Pospesel's How to Add a Decoration View to a UICollectionView

LXReorderableCollectionViewFlowLayout

Und hier ist das Ergebnis: (Bitte ignorieren Sie die Farbinkonsistenz Problem wegen der Grafiken wählte ich sind noch nicht perfekt.)

enter image description here

Was ich tat:

  1. ein eigenes Layout erstellt von einer Klasse von LXReorderableCollectionViewFlowLayout geerbt zu schaffen (zum Neuordnen Zweck), die für die Ansicht für die Ansicht Logo
  2. hinzugefügt, um eine Dekoration Ansicht
  3. Added eine Dekoration Ansicht von UICollectionFlowLayout geerbt die Bücherregale

Aber ich lief in ein paar Probleme:

1. Ich kann überhaupt nicht bewegen, wenn die Einzelteile in einem Bildschirm

Dann können gezeigt werden, fügte ich den folgenden Code, den Content größer

- (CGSize)collectionViewContentSize 
{ 
    return CGSizeMake(self.collectionView.bounds.size.width,  self.collectionView.bounds.size.height+100); 
} 

Dann kann ich scrollen jetzt zu machen. Hier ziehe ich die erste Zeile nach unten:

enter image description here

Sie können sehen, die die Dekoration Ansicht für Logo arbeitet.

2. Aber ich habe den zweiten Satz von Problemen, wenn ich die letzte Zeile nach oben ziehen:

enter image description here

Sie können die Dekoration Ansicht sehen nicht am grünen Kastenteil hinzugefügt wird.

3.Der Hintergrund der Dekorationsansicht für das Bücherregal wird dunkler und dunkler. (Bitte beachten Sie same problem here

4. Das Buchregal Bar manchmal bewegt, wenn ich die Elemente neu anordnen

enter image description here

ich einige der wichtigen Code-Liste hier:

- (void)prepareLayout 
{ 
    // call super so flow layout can do all the math for cells, headers, and footers 
    [super prepareLayout]; 

    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 
    NSMutableDictionary *shelfLayoutInfo = [NSMutableDictionary dictionary]; 

    // decoration view - emblem 
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0]; 
    UICollectionViewLayoutAttributes *emblemAttributes = 
     [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:[EmblemView kind] 
      withIndexPath:indexPath]; 
    emblemAttributes.frame = [self frameForEmblem:YES]; 
    dictionary[[EmblemView kind]] = @{indexPath: emblemAttributes}; 

    // Calculate where shelves go in a vertical layout 
    int sectionCount = [self.collectionView numberOfSections]; 

    CGFloat y = 0; 
    CGFloat availableWidth = self.collectionViewContentSize.width - (self.sectionInset.left + self.sectionInset.right); 
    int itemsAcross = floorf((availableWidth + self.minimumInteritemSpacing)/(self.itemSize.width + self.minimumInteritemSpacing)); 

    for (int section = 0; section < sectionCount; section++) 
    { 
     y += self.headerReferenceSize.height; 
     //y += self.sectionInset.top; 

     int itemCount = [self.collectionView numberOfItemsInSection:section]; 
     int rows = ceilf(itemCount/(float)itemsAcross)+1; // add 2 more empty row which doesn't have any data 
     for (int row = 0; row < rows; row++) 
     { 
      indexPath = [NSIndexPath indexPathForItem:row inSection:section]; 
      shelfLayoutInfo[indexPath] = [NSValue valueWithCGRect:CGRectMake(0,y, self.collectionViewContentSize.width, self.itemSize.height + DECORATION_HEIGHT)]; 
      y += self.itemSize.height; 

      if (row < rows - 1) 
       y += self.minimumLineSpacing; 
     } 

     y += self.sectionInset.bottom; 
     y += self.footerReferenceSize.height; 
    } 

    dictionary[[ShelfView kind]] = shelfLayoutInfo; 

    self.shelfLayoutInfo = dictionary; 
} 


- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 
{ 
    NSArray *attributesArrayInRect = [super layoutAttributesForElementsInRect:rect]; 

    // cell layout info 
    for (BookShelfLayoutAttributes *attribs in attributesArrayInRect) 
    { 

     attribs.zIndex = 1; 
     CATransform3D t = CATransform3DIdentity; 
     t = CATransform3DTranslate(t, 0, 0, 40); 
     attribs.transform3D = CATransform3DRotate(t, 15 * M_PI/180, 1, 0, 0); 
    } 

    // Add our decoration views (shelves) 
    NSMutableDictionary* shelfDictionary = self.shelfLayoutInfo[[ShelfView kind]]; 
    NSMutableArray *newArray = [attributesArrayInRect mutableCopy]; 

    [shelfDictionary enumerateKeysAndObjectsUsingBlock:^(id key, NSValue* obj, BOOL *stop) { 

     if (CGRectIntersectsRect([obj CGRectValue], rect)) 
     { 
      UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:[ShelfView kind] withIndexPath:key]; 
      attributes.frame = [obj CGRectValue]; 

      NSLog(@"decorationView rect = %@",NSStringFromCGRect(attributes.frame)); 
      attributes.zIndex = 0; 
      //attributes.alpha = 0.5; // screenshots 
      [newArray addObject:attributes]; 
     } 
    }]; 

    attributesArrayInRect = [NSArray arrayWithArray:newArray]; 

    NSMutableDictionary* emblemDictionary = self.shelfLayoutInfo[[EmblemView kind]]; 
    NSMutableArray *newArray2 = [attributesArrayInRect mutableCopy]; 
    [emblemDictionary enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath, UICollectionViewLayoutAttributes *attributes, BOOL *innerStop) { 
     if (CGRectIntersectsRect(rect, attributes.frame)) { 
      [newArray2 addObject:attributes]; 
     } 
    }]; 

    attributesArrayInRect = [NSArray arrayWithArray:newArray2]; 

    return attributesArrayInRect; 
} 

Ich freue mich, wenn Sie geduldig genug sind, diesen Beitrag zu lesen und mir Ratschläge oder Vorschläge zu geben, und ich werde den vollständigen Quellcode veröffentlichen, wenn ich alles reparieren kann die Probleme. Vielen Dank im Voraus.

+0

Ich habe einen Beitrag in Apples Forum gefunden. Es scheint, dass die Duplizierung von DecorationView ein Fehler ist. https://devforums.apple.com/message/773776#773776 –

+0

Sie sollten die Inhaltsgröße Ihrer Sammlungsansicht als Teil Ihrer prepareLayout-Funktion berechnen. So wie es aussieht, können Sie unabhängig von der Anzahl der Elemente in der Sammlungsansicht nur 100 Pixel nach unten scrollen. – Ash

Antwort

0

Ich würde vorschlagen, Ihre letzte Zeile zu überprüfen und die [self.collectionView ScrollEnable: NO] gleich für die erste Zeile, legen Sie Hintergrundfarbe clear von collectionView und collectionViewCell und das Bücherregal Bild setzt auf Hintergrundansicht.