2014-10-21 9 views
13

Sto lavorando su UICollectionView con layout personalizzato. In due giorni non riesco a capire come aggiungere l'intestazione a UICollectionView. Ho molto semplice controller della vista (creato nel storyboard con layout personalizzato):Intestazione della sezione in UICollectionView con UICollectionViewLayout personalizzato

class ACollectionViewController: UICollectionViewController { 

    enum Identifiers: String { 
     case CellIdentifier = "Cell" 
     case HeaderIdentifier = "Header" 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.collectionView.registerClass(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: Identifiers.HeaderIdentifier.rawValue) 
    } 

    // MARK: UICollectionViewDataSource 
    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { 
     return 1 
    } 

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 10 
    } 

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.CellIdentifier.rawValue, forIndexPath: indexPath) as Cell 
     cell.backgroundColor = UIColor.redColor() 
     return cell 
    } 

    override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView { 
     println("ip = \(indexPath.item)") 
     var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView 
     supplementaryView.backgroundColor = UIColor.blueColor() 
     return supplementaryView 
    } 

E qui è il mio layout personalizzato:

class ALayout: UICollectionViewLayout { 

    override func prepareLayout() { 
     super.prepareLayout() 
    } 

    override func collectionViewContentSize() -> CGSize { 
     return self.collectionView!.bounds.size 
    } 

    let itemWidth = 40 
    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! { 
     var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath) 

     let x: Float = Float(10) * Float(indexPath.item) 
     let y: Float = Float(indexPath.item * itemWidth) 
     attributes.frame = CGRect(x: CGFloat(x), y: CGFloat(y), width: CGFloat(itemWidth), height: CGFloat(itemWidth)) 

     return attributes 
    } 

    override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? { 
     var attributes = [UICollectionViewLayoutAttributes]() 

     let sectionsCount = self.collectionView!.dataSource!.numberOfSectionsInCollectionView!(self.collectionView!) 
     for section in 0..<sectionsCount { 
      /// add header 
      attributes.append(self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: NSIndexPath(forItem: 0, inSection: section))) 

      let itemsCount = self.collectionView!.numberOfItemsInSection(section) 
      for item in 0..<itemsCount { 
       let indexPath = NSIndexPath(forItem: item, inSection: section) 
       attributes.append(self.layoutAttributesForItemAtIndexPath(indexPath)) 
      } 
     } 

     return attributes 
    } 

    override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! { 
     var attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, withIndexPath: indexPath) 
     attributes.frame = CGRect(x: 0, y: 0, width: 320, height: 50) 

     return attributes 
    } 
} 

Il problema è che non capisco come aggiungere la sezione intestazione corretta, quale indexPath di questa intestazione dovrebbe essere. C'è il commento nel codice dove viene aggiunta l'intestazione. App si blocca all'avvio con l'errore

2014-10-21 13:06:22.793 UICollectionViewLayout-Demo[3805:95924] *** Terminating app due to 
uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of 
kind: UICollectionElementKindCell with identifier Header - must register a nib or a class for 
the identifier or connect a prototype cell in a storyboard' 

E capisco, questo è perché cella ha la stessa indexPath come intestazione di sezione che sto cercando di aggiungere, ma quale dovrebbe essere indexPath della testata? O forse lo sto facendo completamente storto?

Grazie in anticipo.

risposta

9

tuo incidente derivante dal fatto che si sta utilizzando

var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView 

per cercare di annullare l'accodamento l'intestazione e piè di pagina (in collectionView:viewForSupplementaryElementOfKind). Cambiare a

var supplementaryView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier:Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView 

dovrebbe sbarazzarsi del crash, in modo da poter studiare l'indexPath. Ma sul mio test, indexPath è sempre solo "0".

1

Invece di var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView

Dovrebbe essere

let supplementaryView = collectionView.dequeueReusableSupplementaryViewOfKind(kind withReuseIdentifier:Identifiers.HeaderIdentifier.rawValue, forIndexPath:indexPath) 
1

Si sta utilizzando la funzione sbagliato per intestazione. Come per l'utilizzo di documentazione mela quanto segue per intestazione e piè di pagina:

func dequeueReusableSupplementaryViewOfKind(_ elementKind: String, 
         withReuseIdentifier identifier: String, 
           forIndexPath indexPath: NSIndexPath!) -> AnyObject 

invece di:

var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView 
Problemi correlati