使用具有超级图层的视图作为图层蒙版 [英] Using a view with a superlayer as a layer mask
问题描述
我有一个视图,该视图要覆盖一个透明的黑色层,其边缘与该视图完全匹配.该视图不会限制其边界,因此子视图可能会停止运行.
I have a view that I want to overlay with a transparent black layer whose edges match the view exactly. The view does not clip its bounds, so subviews may be hanging off.
显而易见的解决方案是 CALayer
的 mask
属性,但是文档说遮罩层一定不能有超层" 或行为未定义.
The obvious solution is the mask
property of CALayer
, but the docs say that the mask layer "must not have a superlayer" or the behavior is undefined.
我希望使用该视图的 presentationLayer
是一种有效的解决方法,但是我认为我不完全理解什么表示层,因为该属性返回 nil 代码>.
I was hoping that using the presentationLayer
of that view would be an effective workaround, but I don't think I fully understand what presentation layers are, as that property returns nil
.
有人对我如何遮罩透明的黑色层以匹配将在其上绘制的视图的形状有提示吗?谢谢.
Does anyone have tips on how I could mask my transparent black layer to match the shape of the view over which it will be drawn? Thanks.
推荐答案
对此,还有一个不太明显的解决方案,它应该比屏蔽效果更好:混合模式过滤器,特别是 CI合成过滤器,它将使这些图层变暗,而不会影响其边界之外的任何内容.另外,与遮罩叠加方法不同,您可以在边缘获得正确的抗锯齿效果.
There’s a less obvious solution to this that should work better than masking: a blend-mode filter, specifically 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, it will dim those layers without affecting anything outside of their boundaries. As a bonus, you’ll get correct antialiasing at the edges, unlike the masked-overlay approach.
这是一个例子.出于说明目的,我将调光层设置为仅覆盖其高度的一半,但是您当然希望使其变大.
Here’s an example. For illustrative purposes I made the dimming layer only half the height of the area it covers, but you’d of course want to make it larger.
>
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)
这篇关于使用具有超级图层的视图作为图层蒙版的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!