问题描述
我有一个视图,我想用一个透明的黑色图层覆盖它,该图层的边缘与视图完全匹配。视图不会裁剪其边界,因此子视图可能会挂起。
显而易见的解决方案是 mask
的 CALayer
属性,但文档说遮罩层“不得有超层”,否则行为未定义。
我希望使用该视图的 presentationLayer
是一种有效的解决方法,但我不认为我完全理解表示层是什么,因为该属性返回 nil
。
有没有人有关于如何屏蔽我的透明黑色图层以匹配将在其上绘制的视图形状的提示?谢谢。
解决方法
对此有一个不太明显的解决方案,它应该比遮罩效果更好:混合模式过滤器,特别是 source-atop。如果您将透明图层添加为它应该变暗的图层的同级,并为其分配适当的 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,1)
let dimmedLayer2 = CALayer()
dimmedLayer2.frame = CGRect(x: 80,y: 80,height: 100)
dimmedLayer2.backgroundColor = NSColor.systemPurple.cgColor
dimmedLayer2.transform = CATransform3DMakeRotation(-0.1,1)
let dimmingLayer = CALayer()
dimmingLayer.frame = CGRect(x: 0,y: 50,height: 100)
dimmingLayer.backgroundColor = NSColor(white: 0,alpha: 0.5).cgColor
dimmingLayer.compositingFilter = CIFilter(name: "CISourceAtopCompositing")
dimmedRoot.sublayers = [ dimmedLayer1,dimmedLayer2,dimmingLayer ]
container.addSublayer(dimmedRoot)