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.wantsDefaultClipping
和CALayer.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
.
期间设置了阴影属性
我的视野需要阴影。我尝试使用视图的 NSShadow
功能,但在滚动视图中使用它太慢了。我想尝试使用图层的阴影属性来提高性能。
在我的 NSView.updateLayer()
方法中,我设置了以下属性:
layer.shadowOffset = CGSize(width: 0, height: -3)
layer.shadowRadius = 3
layer.shadowColor = NSColor.black().cgColor
layer.shadowOpacity = 0.3
没有显示阴影。我也试过把NSView.wantsDefaultClipping
和CALayer.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
.