Il prossimo OSX 10.10 ("Yosemite") offre un nuovo tipo di visualizzazione, NSVisualEffectView, che supporta la traslucenza attraverso la finestra o all'interno della finestra. Sono principalmente interessato alla traslucenza attraverso la finestra, quindi mi concentrerò su questo in questa domanda, ma si applica anche alla traslucenza all'interno della finestra.Come utilizzare NSVisualEffectView retrocompatibile con OSX <10.10?
L'utilizzo della traslucenza attraverso la finestra in 10.10 è banale. Devi solo inserire un NSVisualEffectView
da qualche parte nella tua gerarchia di visualizzazione e impostarlo su blendingMode
su NSVisualEffectBlendingModeBehindWindow
. Questo è tutto ciò che serve.
Sotto 10.10 è possibile definire NSVisualEffectView
s in IB, impostare la proprietà della modalità di fusione e si è in esecuzione.
Tuttavia, se si desidera essere retrocompatibili con versioni OSX precedenti, non è possibile farlo. Se si tenta di includere un NSVisualEffectView
nel proprio XIB, si verificherà un arresto anomalo non appena si tenta di caricare XIB.
Voglio una soluzione "imposta e dimentica" che offrirà traslucenza quando viene eseguito in 10,10 e semplicemente si riduce a una vista opaca quando si esegue su versioni precedenti del sistema operativo.
Quello che ho fatto finora è di rendere la vista in questione un normale NSView in XIB, e quindi aggiungere il codice (chiamato da awakeFromNib) che controlla per [NSVisualEffectView class] != nil
, e quando è definita la classe, creo un istanza di NSVisualEffectView, sposta tutte le sottoview della mia vista corrente nella nuova vista e la installa in posizione. Funziona, ma è un codice personalizzato che devo scrivere ogni volta che voglio una vista traslucida.
Sto pensando che questo potrebbe essere possibile utilizzando un oggetto NSProxy. Ecco cosa sto pensando:
Definire una sottoclasse personalizzata di NSView (chiamiamola MyTranslucentView). In tutti i metodi init (initWithFrame e initWithCoder) butterei via l'oggetto appena creato e invece creo una sottoclasse di NSProxy che ha una variabile di istanza privata (myActualView). All'inizio, deciderebbe di creare l'oggetto myActualView come NSVisualEffectView se OS> = 10.10 e un normale NSView in OS < 10.10.
Il proxy inoltrerà i messaggi ALL a myActualView.
Questa sarebbe una buona quantità di codice pignolo e di basso livello, ma penso che dovrebbe funzionare.
Qualcuno ha fatto qualcosa del genere? In tal caso, puoi indicarmi la direzione giusta o darmi qualche suggerimento?
Apple è MOLTO più aperto con il contratto Beta con Yosemite a rispetto ai precedenti Betas. Non penso di violare la mia Beta NDA parlando di questo in termini generali, ma il codice effettivo utilizzando NSVisualEffectView
probabilmente dovrebbe essere condiviso in NDA ...
Un'altra soluzione potrebbe essere quella di utilizzare una categoria su 'NSView', qualcosa come '- (id) initVisualEffectView' che produce l'effetto, restituendo un' NSView' o un 'NSVisualEffectView' poiché immagino che erediti da' NSView'. O se stai usando pennini, forse '- (void) applyVisualEffectView' (a self). – Larme
Che cosa farebbe il metodo category per le viste basate su pennini? Immagino che potrebbe creare una nuova vista che è l'intera dimensione della vista, spostare tutti i contenuti della vista su quella vista e renderla l'unica sottoview della vista. Potrebbe funzionare ... –
@Larme, avrei dovuto taggarti nel mio commento di risposta in modo da ricevere una notifica ... –