2016-02-23 5 views
7

Sto sperimentando con la nuova API NSCollectionView, introdotta in El Capitan.NSCollectionView dataSource non funziona correttamente

Dopo il video WWDC, creo una sottoclasse di NSCollectionViewFlowLayout per determinare il layout della vista di raccolta.

class Layout : NSCollectionViewFlowLayout { 

    override func prepareLayout() { 

    super.prepareLayout() 

    self.minimumInteritemSpacing = 0 
    self.minimumLineSpacing = 0 

    let cheight = self.collectionView!.bounds.height 
    let cwidth = self.collectionView!.bounds.width 

    self.itemSize = CGSizeMake(cwidth/2.0, cheight/6.0) 

    } 

} 

Dopo di che, ho creato una sottoclasse NSObject a servire come fonte di dati.

class DataSource : NSObject, NSCollectionViewDataSource { 

    func collectionView(collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int { 
    return 5 
    } 

    func collectionView(collectionView: NSCollectionView, itemForRepresentedObjectAtIndexPath indexPath: NSIndexPath) -> NSCollectionViewItem { 

    /* DOESN'T GET CALLED! */ 

    let item = collectionView.makeItemWithIdentifier("cell", forIndexPath: indexPath) 

    item.view.wantsLayer = true 
    item.view.layer?.backgroundColor = NSColor.redColor().CGColor 

    return item 

    } 

} 

Il problema è checollectionView:itemForRepresentedObjectAtIndexPath: non viene mai chiamato.

Questo è come mi inizializzare il panorama collezione:

let collectionView = NSCollectionView(frame: view.bounds) 

let dataSource = DataSource() 
let layout = Layout() 

collectionView.collectionViewLayout = layout 
collectionView.registerClass(NSCollectionViewItem.self,  
          forItemWithIdentifier: "cell") 
collectionView.dataSource = dataSource 

collectionView.backgroundColors = [.blackColor()] 

posso vedere chiaramente la vista nella sua collezione superview, ma non ci sono le cellule.

Inoltre, questa linea, se chiamata all'esterno del delegato (ma dopo che la classe della cella è stata registrata) fa arrestare l'app!

let item = collectionView.makeItemWithIdentifier("cell", forIndexPath: /*any index path*/) 

sto facendo qualcosa di sbagliato o è NSCollectionView nuova API rotto?

Grazie.

+0

Questa è probabilmente una domanda stupida, ma stai aggiungendo la vista raccolta alle sottoview della tua vista, giusto? – Aaron

+0

@ Arar I sono. Riesco a vedere la vista raccolta nella sua superview (senza celle) –

+1

come sai che il metodo non è stato chiamato? hai impostato qualche breakpoint all'interno di quel metodo? o hai provato a registrare qualcosa nel corpo del metodo? è il tuo file 'cell.xib' nello stesso pacchetto? o crei l'interfaccia a livello di programmazione (come hai registrato un _class_ ma non un _nib_)? hai modificato il modulo di flusso della vista raccolta _ "legacy" _ ad es. _ "flusso" _ in IB? – holex

risposta

0

Il metodo makeItemWithIdentifier è fondamentale e cerca .xib "cellula" di nome in voi bundle: potrebbe essere necessario registrarlo con registerNib: forItemWithIdentifier: se viene da un altro fascio.

Così il problema viene prima che, dal momento che il CollectionView: itemForRepresentedObjectAtIndexPath non viene mai chiamato e questo potrebbe derivare dal vostro modello: perché si fa a creare una nuova classe di servire come origine dati e non utilizzare la stessa NSViewController cui risiede NSCollectionView ?

Lo faccio sempre e con la nuova API tutto funziona perfettamente. Spero che questo possa aiutarti!

+0

Sto provando a creare la vista di raccolta a livello di codice, ecco perché I ' m usando 'registerClass: forItemWithIdentifier:' piuttosto che 'registerNib: forItemWIthIdentifier'. –

+0

Ho provato anche registerClass e registerNib senza fortuna. numberOfItemsInSection viene chiamato ma itemForRepresentedObjectAtIndexPath no. – empedocle

0

Avevo quasi lo stesso problema, ed ecco come l'ho risolto.

Prima di tutto il problema che ho avuto:

  • quando mio avviso collezione delegato non è stato attuando il protocollo NSCollectionViewDelegateFlowLayout, tutto è andato bene e il CollectionView: metodo di itemForRepresentedObjectAtIndexPath stato chiamato
  • quando mio avviso collezione delegato era l'attuazione del protocollo di NSCollectionViewDelegateFlowLayout, CollectionView: metodo itemForRepresentedObjectAtIndexPath NON è stato chiamato

ho commentato fuori ogni NSColl ectionViewDelegateFlowLayout metodo nel delegato, e si è scoperto che se il metodo collectionView: layout: referenceSizeForHeaderInSection: è stato commentato, quindi tutto andava bene di nuovo (anche se io non uso le intestazioni).

È risultato che collectionView: layout: referenceSizeForHeaderInSection: restituiva un NaN invece di 0.0 come larghezza nella dimensione (errore di copia/incolla stupido).

Sei sicuro di non avere lo stesso tipo di problema in ciò che il tuo layout sta tornando?

0

Il problema che ho riscontrato è che non ho registrato né pennino né classe per gli elementi della vista raccolta. I sintomi erano esattamente come quelli che descrivi - numberOfItemsInSection è stato chiamato e itemForRepresentedObjectAtIndexPath no. Dopo aver registrato un pennino, il metodo ha iniziato a essere invocato. Ecco la risposta pertinente - https://stackoverflow.com/a/39516035/4635852