AFAIK,您不能将图层屏蔽到路径的反面。
一些观察结果:
-
如果您只是想删除整个视图内的路径,则可以通过创建由整个视图组成的路径来实现这一点CGRect
加上各种内部路径并利用偶数/奇数缠绕/填充规则,但如果您的内部路径彼此重叠,则这将不起作用。
-
您可以将图像遮罩到路径的反面(通过创建单独的“图像遮罩”),但这不适用于动态CALayer
掩蔽。它用于屏蔽NSImage
。因此,如果您同意对视图的筛选部分使用快照,那么这是一个选项。
有关使用图像蒙版的示例,请参阅下面的代码片段。
-
另一种方法是将过滤器应用于整个视图,对其进行快照,将该快照放在相关视图下方,然后将顶级视图屏蔽到内部路径。实际上,将未过滤的视图屏蔽到内部路径,显示其下方视图的过滤快照。
-
然而,方法是创建一条代表所有内部路径联合轮廓的路径。如果路径很简单(例如非旋转矩形),这非常简单。如果路径很复杂(一些是旋转的,一些是非矩形路径等),这会变得很棘手。但这个微不足道的场景还不算太糟糕。不管怎样,如果你这样做了,那么你就可以回到那个奇偶技巧了。
我对这些方法都不完全满意,但我没有看到任何其他方法来实现您正在寻找的东西。希望有人能提出一些更好的方法来解决这个问题。
要扩展选项 2(使用通过绘制几条路径(可能重叠)创建的图像蒙版),在 Swift 3 中您可以执行以下操作:
private func maskImageWithPaths(image: NSImage, size: CGSize) -> NSImage {
// define parameters for two overlapping paths
let center1 = CGPoint(x: size.width * 0.40, y: size.height / 2)
let radius1 = size.width * 0.20
let center2 = CGPoint(x: size.width * 0.60 , y: size.height / 2)
let radius2 = size.width * 0.20
// create these two overlapping paths
let path = CGMutablePath()
path.move(to: center1)
path.addArc(center: center1, radius: radius1, startAngle: -.pi / 2, endAngle: .pi * 3 / 2, clockwise: false)
path.move(to: center2)
path.addArc(center: center2, radius: radius2, startAngle: -.pi / 2, endAngle: .pi * 3 / 2, clockwise: false)
// create image from these paths
let imageRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(size.width), pixelsHigh: Int(size.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSDeviceRGBColorSpace, bitmapFormat: .alphaFirst, bytesPerRow: 4 * Int(size.width), bitsPerPixel: 32)!
let context = NSGraphicsContext(bitmapImageRep: imageRep)!
context.cgContext.addPath(path)
context.cgContext.setFillColor(NSColor.blue.cgColor)
context.cgContext.fillPath()
let maskImage = context.cgContext.makeImage()!
let mask = CGImage(maskWidth: Int(size.width), height: Int(size.height), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: 4 * Int(size.width), provider: maskImage.dataProvider!, decode: nil, shouldInterpolate: true)!
let finalImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil)!.masking(mask)!
return NSImage(cgImage: finalImage, size: size)
}
得出:
这会掩盖绘制的路径。