macOS:CALayer 阴影未显示

macOS: CALayer shadow not showing

我的视野需要阴影。我尝试使用视图的 NSShadow 功能,但在滚动视图中使用它太慢了。我想尝试使用图层的阴影属性来提高性能。

在我的 NSView.updateLayer() 方法中,我设置了以下属性:

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

没有显示阴影。我也试过把NSView.wantsDefaultClippingCALayer.masksToBounds设置成false,但是还是没有影子。

为什么使用CALayer阴影属性时没有阴影?

您需要补充的是:

self.view.wantsLayer = true

我尝试了运行下面的代码;该层确实显示以及阴影:

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)

顺便说一下,您在以下行中有一个错字:

NSColor.black().cgColor

应该是:

NSColor.blackColor().CGColor

我查看了 CALayer.render(in:) 的反汇编,看起来它正在正确访问图层阴影属性。所以 NSView 可能会在每个绘制周期中用自己的阴影属性覆盖图层阴影属性。最重要的是,您只能通过在视图上使用 shadow 属性 将阴影添加到视图支持层。

虽然我确实解决了我的滚动性能问题。我在滚动过程中分析了我的应用程序,并注意到 CGContextEndTransparencyLayer 中阴影图像的创建导致 CPU 激增。

创建阴影有两个步骤。首先,必须根据上面像素的 alpha 通道计算阴影的路径。其次,应用高斯模糊以柔化阴影的边缘。

因为我知道阴影顶部的视图是完全不透明的,所以我知道路径将只是视图的边界。我可以通过设置层的 shadowPath 属性 来跳过第一步。但不幸的是,图层的阴影属性被没有 shadowPath 属性.

的视图覆盖

我的解决方案是创建一个容器视图,在内容视图下方绘制一个矩形阴影图像。此阴影图像创建一次并缓存,显着提高滚动性能。并且由于自动布局的强大功能(特别是对齐矩形插入),容器视图无需手动调整阴影即可使用。

你可以查看我的代码on GitHub

NSView 在可预测的时间设置 CALayer 上的阴影相关属性,例如当 wantsLayer 设置为 true 以及将视图添加到父视图时。在NSView之后设置图层阴影属性,阴影就会可见。我在 resizeSubviews.

期间设置了阴影属性