2016-07-24 51 views
1

Ich brauche einen Schatten aus meiner Sicht. Ich habe versucht, die NSShadow Fähigkeit der Ansicht zu verwenden, aber es ist zu langsam, um in einer Bildlaufansicht zu verwenden. Ich möchte versuchen, die Schatteneigenschaften der Ebene zu verwenden, um die Leistung hoffentlich zu verbessern.macOS: CALayer shadow wird nicht angezeigt

In meiner NSView.updateLayer() Methode, habe ich die folgenden Eigenschaften:

layer.shadowOffset = CGSize(width: 0, height: -3) 
layer.shadowRadius = 3 
layer.shadowColor = NSColor.black().cgColor 
layer.shadowOpacity = 0.3 

Kein Schatten dargestellt ist. Ich habe auch versucht, NSView.wantsDefaultClipping und CALayer.masksToBounds auf false zu setzen, aber es gibt immer noch keinen Schatten.

Warum gibt es keinen Schatten bei Verwendung der Schatteneigenschaften CALayer?

Antwort

0

I:

NSColor.black().cgColor 

wie es sein sollte schaute auf die Demontage von CALayer.render(in:) und es sah aus wie es richtig auf die Layer Schatten Eigenschaften zugreifen. So überschreibt NSView wahrscheinlich die Schatteneigenschaften des Layers bei jedem Zeichenzyklus mit seinen eigenen. Die Quintessenz ist, dass Sie nur Schatten zu View-Backing-Layern hinzufügen können, indem Sie die shadow -Eigenschaft in der Ansicht verwenden.

Ich habe zwar mein Scroll-Performance-Problem gelöst. Ich profilierte meine App während einer Scroll und bemerkte, dass die Erstellung des Shadow-Images in CGContextEndTransparencyLayer die CPU zum Spike veranlasste.

Es gibt zwei Schritte zum Erstellen eines Schattens. Zuerst muss ein Pfad für den Schatten basierend auf dem Alpha-Kanal der Pixel oben berechnet werden. Zweitens wird eine Gaußsche Unschärfe angewendet, um die Ränder des Schattens weicher zu machen.

Da ich weiß, dass die Ansicht oben auf dem Schatten vollständig undurchsichtig ist, weiß ich, dass der Pfad einfach die Grenzen der Ansicht sein wird. Ich hätte den ersten Schritt überspringen können, indem ich die Eigenschaft shadowPath des Layers gesetzt habe. Leider werden die Schatteneigenschaften der Ebene durch die Ansicht überschrieben, die keine shadowPath Eigenschaft besitzt.

Meine Lösung bestand darin, eine Containeransicht zu erstellen, die ein rechteckiges Schattenbild unterhalb der Inhaltsansicht zeichnet. Dieses Schattenbild wird einmal erstellt und im Cache gespeichert, wodurch die Scroll-Leistung drastisch erhöht wird. Und dank der leistungsstarken Auto-Layout-Funktion (speziell der Ausrichtungs-Rect-Einfügungen) kann die Containeransicht verwendet werden, ohne dass der Schatten manuell angepasst werden muss.

Sie können meinen Code on GitHub ansehen.

1

Was müssen Sie hinzufügen, ist:

self.view.wantsLayer = true 

ich den folgenden Code versucht läuft; die Schicht als Schatten auch nicht zeigen:

let layer = CALayer() 
layer.frame = CGRect(x: 50, y: 50, width: 100, height: 100) 

layer.backgroundColor = NSColor.redColor().CGColor 

layer.shadowOffset = CGSize(width: 0, height: -3) 
layer.shadowRadius = 3 
layer.shadowColor = NSColor.blackColor().CGColor 
layer.shadowOpacity = 1.0 //Or: 0.3 as you originally have 
self.view.wantsLayer = true 
self.view.layer?.addSublayer(layer) 

By the way, haben Sie einen Tippfehler in der folgenden Zeile:

NSColor.blackColor().CGColor 
+0

Danke! Aber ich habe speziell über View-Backing-Layer gesprochen, nicht über Standalone-Layer. Außerdem ist '.cgColor' in Swift 3 kein Tippfehler :-) – fumoboy007