简体   繁体   English

macOS:CALayer 阴影未显示

[英]macOS: CALayer shadow not showing

I need a shadow on my view.我的视线需要阴影。 I tried using the view's NSShadow capability, but it is too slow to use in a scroll view.我尝试使用视图的NSShadow功能,但在滚动视图中使用它太慢了。 I want to try using the layer's shadow properties to hopefully improve performance.我想尝试使用图层的阴影属性来提高性能。

In my NSView.updateLayer() method, I set the following properties:在我的NSView.updateLayer()方法中,我设置了以下属性:

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

No shadow is shown.不显示阴影。 I tried also setting NSView.wantsDefaultClipping and CALayer.masksToBounds to false , but there is still no shadow.我也尝试将NSView.wantsDefaultClippingCALayer.masksToBounds设置为false ,但仍然没有阴影。

Why is there no shadow when using the CALayer shadow properties?为什么使用CALayer阴影属性时没有阴影?

What you need to add is:您需要添加的是:

self.view.wantsLayer = true

I tried running the following code;我尝试运行以下代码; the layer does show as well as the shadow:该层确实显示以及阴影:

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, you have a typo on the following line:顺便说一句,您在以下行中有一个错字:

NSColor.black().cgColor

as it should be:应该是这样:

NSColor.blackColor().CGColor

I looked at the disassembly of CALayer.render(in:) and it looked like it was properly accessing the layer shadow properties.我查看了CALayer.render(in:)的反汇编,看起来它正在正确访问图层阴影属性。 So NSView probably overwrites the layer shadow properties with its own on every draw cycle.所以NSView可能会在每个绘制周期用它自己的覆盖层阴影属性。 The bottom line is that you can only add shadows to view-backing layers by using the shadow property on the view.最重要的是,您只能通过在视图上使用shadow属性向视图支持层添加阴影。

I did solve my scroll performance problem though.不过,我确实解决了我的滚动性能问题。 I profiled my app during a scroll and noticed that the creation of the shadow image in CGContextEndTransparencyLayer was causing the CPU to spike.我在滚动过程中分析了我的应用程序,并注意到在CGContextEndTransparencyLayer创建阴影图像导致 CPU 飙升。

There are two steps for creating a shadow.创建阴影有两个步骤。 First, a path for the shadow has to be computed based on the alpha channel of the pixels above.首先,必须根据上面像素的 alpha 通道计算阴影的路径。 Second, a gaussian blur is applied in order to soften the edges of the shadow.其次,应用高斯模糊以柔化阴影的边缘。

Since I know the view on top of the shadow is fully opaque, I know the path will be simply the view's bounds.因为我知道阴影顶部的视图是完全不透明的,所以我知道路径将只是视图的边界。 I could have skipped the first step by setting the layer's shadowPath property.我可以通过设置图层的shadowPath属性跳过第一步。 But unfortunately, the layer's shadow properties are overridden by the view which doesn't have a shadowPath property.但不幸的是,图层的阴影属性被没有shadowPath属性的视图覆盖。

My solution was to create a container view that draws a rectangular shadow image underneath the content view.我的解决方案是创建一个容器视图,在内容视图下方绘制一个矩形阴影图像。 This shadow image is created once and cached, increasing scroll performance dramatically.此阴影图像创建一次并缓存,显着提高了滚动性能。 And thanks to the power of Auto Layout (specifically, the alignment rect insets), the container view can be used without having to manually adjust for the shadow.并且由于自动布局的强大功能(特别是对齐矩形插入),可以使用容器视图而无需手动调整阴影。

You can view my code on GitHub .你可以在 GitHub 上查看我的代码。

NSView sets the shadow related properties on CALayer at predictable times, like when wantsLayer is set to true and when the view is added to a superview. NSView在可预测的时间在CALayer上设置与阴影相关的属性,例如当wantsLayer设置为 true 以及将视图添加到wantsLayer视图时。 Set the layer shadow properties after NSView and the shadow will be visible.NSView之后设置图层阴影属性,阴影将可见。 I set the shadow properties during resizeSubviews .我在resizeSubviews期间设置了阴影属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM