2010-09-05 9 views
7

ho una visione strato di hosting istituito come questo in un costume NSView sottoclasse:Calling setNeedsDisplay: SI sul layer-hosting vista non ridisegna la vista

[self setLayer:rootLayer]; 
[self setWantsLayer:YES]; 

aggiungo tutti i sottolivelli all'albero strato di dopo ho chiamato setNeedsDisplay su ogni sottolivello. Il contenuto di ogni livello è fornito dal metodo drawLayer:inContext del delegato del mio livello.

Ecco il mio problema:

Dopo l'inizializzazione mio punto di vista il panorama diventa disegnare correttamente. Tuttavia, quando il modello è cambiato e chiamo il [myCustomView setNeedsDisplay:YES]; dal mio controller di visualizzazione, non viene chiamato lo drawLayer:inContext.

Sono confuso ora come aggiornare la vista:

  • Devo chiamare il metodo setNeedsDisplay su ogni CALayer nell'albero strato?
  • Non dovrebbe la chiamata di setNeedsDisplay:YES nella vista di hosting del livello stesso attivare il ridisegno dell'intero albero dei livelli?

Grazie per il vostro aiuto.

Modifica

ho trovato qualcosa nella classe NSView riferimento

Una vista layer-backed è una vista che è sostenuta da uno strato di Core Animation. Qualsiasi disegno eseguito dalla vista è memorizzato nella cache nel livello di supporto. Hai configurato una vista supportata da livelli semplicemente richiamando setWantsLayer: con un valore di YES. La classe vista creerà automaticamente un livello di supporto per te e utilizzerai i meccanismi di disegno della classe vista. Quando si utilizzano viste supportate da livelli, non si dovrebbe mai interagire direttamente con il livello.

Una vista di hosting del livello è una vista che contiene un livello Animazione core che si desidera manipolare direttamente. Crei una vista di hosting dei livelli istanziando un'istanza di una classe di livello Core Animation e impostando tale livello utilizzando il metodo setLayer: view. Dopo averlo fatto, invochi setWantsLayer: con un valore di YES. Quando si utilizza una vista di hosting del livello non si deve fare affidamento sulla vista per il disegno, né si dovrebbero aggiungere subviews alla vista di hosting del livello.

link to documentation

Nel mio caso ho una visione layer-hosting. Quindi vuol dire che devo attivare manualmente il ridisegno? Devo implementare un metodo pseudo drawRect nella NSView personalizzata per chiamare il setNeedsDisplay appropriato sui CALayer che sono stati modificati?

risposta

9

Dopo ulteriori ricerche su Apple sample code di un menu in stile chiosco, ho scoperto che se si utilizza una vista di hosting del livello, è necessario occuparsi degli aggiornamenti dello schermo che sono necessari a causa delle modifiche del modello. Chiamare setNeedsDisplay:YES su NSView non farà nulla.

Quindi, cosa si deve fare se si deve aggiornare una vista, si dovrebbe scrivere un metodo come reloadData e in esso si dovrebbe chiamare setNeedsDisplay su ogni CALayer che necessita di un aggiornamento. Non sono ancora sicuro se una chiamata a questo metodo sul livello radice si propagherà attraverso tutti i livelli figli, ma io non la penso così.

Ho risolto il problema ora chiamando setNeedsDisplay sui singoli CALayer che necessitavano di ricollocamento. Funziona senza problemi.

+0

Il tuo link al codice di esempio è rotto, forse questa è la sostituzione: https://developer.apple.com/library/mac/samplecode/CoreAnimationKioskStyleMenu/Introduction/Intro.html#//apple_ref/doc/uid/ DTS40009512 –

2

V'è anche una pratica spesso utilizzata di avere un "drawRect" vuoto, alla -(void) drawRect:(NSRect)dirtyRect {} center costringere cose nel disegno, Credo con buona ole view.needsDisplay = YES;.

e va notato .. che ciò che sta effettivamente accadendo è che - pronunciando la NSView *view; è layer.delegate = view; provoca lo strato da trarre quando [layer setNeedsDisplay]; si chiama .... via - (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {...} ..

lungo lo stesso vena ... quando dice layer.layoutManager = view ... successive richieste che [layer setNeedsLayout]; si compirà solo quando viene implementato il metodo - (void) layoutSublayersOfLayer:(CALayer *)layer {..} ..

Questi concetti vitali sono sorvolata/sparsi circa in documenti di Apple ... e sono davvero così fondamentale per far funzionare assolutamente qualsiasi cosa.

+0

puoi spiegare un po 'più la strada per i principianti. – carbonr

+0

@carbonr So che è confuso. Ma quello che ho detto è tanto semplice quanto diventa. Se le cose non vengono visualizzate correttamente e la vista è delegata al livello. Devi implementare 'drawLayer: inContext' e magari avere un' drawRect: 'E chiama' setNeedsDisplay'. Leggetelo 10 volte se necessario, ma le informazioni sono tutte lì. Se ricordo bene, lo è. ;) –

Problemi correlati