使用带有超层的视图作为图层蒙版

Using a view with a superlayer as a layer mask

我有一个视图,我想覆盖一个透明的黑色层,其边缘与视图完全匹配。视图不会裁剪其边界,因此子视图可能会挂起。

明显的解决方案是 CALayermask 属性,但是文档说遮罩层 “不能有超级层” 或行为未定义。

我希望使用该视图的 presentationLayer 是一种有效的解决方法,但我不认为我完全理解什么是表示层,因为 属性 returns nil.

有没有人告诉我如何屏蔽我的透明黑色图层以匹配将在其上绘制的视图的形状?谢谢

有一个不太明显的解决方案应该比遮罩效果更好:混合模式滤镜,特别是 source-atop. If you add your transparent layer as a sibling of the layers it’s supposed to dim, and assign it the appropriate CI compositing filter,它会使这些图层变暗而不影响其边界之外的任何东西。作为奖励,您将在边缘获得正确的抗锯齿效果,这与蒙版叠加方法不同。

举个例子。为了便于说明,我将调光层的高度设置为它所覆盖区域的一半高度,但你当然希望将它做得更大。

let container = CALayer()
container.backgroundColor = NSColor.systemBlue.cgColor
container.frame = CGRect(x: 0, y: 0, width: 200, height: 200)

let dimmedRoot = CALayer()
let dimmedLayer1 = CALayer()
dimmedLayer1.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
dimmedLayer1.backgroundColor = NSColor.systemGreen.cgColor
dimmedLayer1.transform = CATransform3DMakeRotation(0.3, 0, 0, 1)

let dimmedLayer2 = CALayer()
dimmedLayer2.frame = CGRect(x: 80, y: 80, width: 100, height: 100)
dimmedLayer2.backgroundColor = NSColor.systemPurple.cgColor
dimmedLayer2.transform = CATransform3DMakeRotation(-0.1, 0, 0, 1)

let dimmingLayer = CALayer()
dimmingLayer.frame = CGRect(x: 0, y: 50, width: 200, height: 100)
dimmingLayer.backgroundColor = NSColor(white: 0, alpha: 0.5).cgColor
dimmingLayer.compositingFilter = CIFilter(name: "CISourceAtopCompositing")

dimmedRoot.sublayers = [ dimmedLayer1, dimmedLayer2, dimmingLayer ]

container.addSublayer(dimmedRoot)