OStack程序员社区-中国程序员成长平台

标题: ios - 组合重叠的 UIBezierPaths 以创建单个蒙版 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 17:29
标题: ios - 组合重叠的 UIBezierPaths 以创建单个蒙版

我希望在我的 View 中创建一个形状像几个圆圈的蒙版。这里 blurView 是我想要剪切的 View ,frames 包含这些圆形/椭圆的 CGRect 帧值。

let holes = UIBezierPath()
 for f in frames {
      let p = UIBezierPath(ovalInRect: f)
      holes.appendPath(p)
}

 let path = UIBezierPath(rect: blurView.bounds)
 path.appendPath(holes)
 path.usesEvenOddFillRule = true
 let mask = CAShapeLayer()
 mask.path = path.CGPath
 mask.fillRule = kCAFillRuleEvenOdd
 blurView.layer.mask = mask

这很好用,除了当圆圈重叠时,blurView 的内容会显示出来,而不是它下面的 View 。我该如何解决?

编辑:使用 Rob 的答案,我到达了某个地方,但不是我想去的地方。蒙版边缘参差不齐,缺乏抗锯齿:

screenshot

有什么办法解决吗?



Best Answer-推荐答案


基本思想是用不透明的颜色填充位图上下文,然后清除我们想要剪辑的任何内容。抓取该位图上下文的图像并用作蒙版。

如果您愿意,可以将其复制到 Playground :

import UIKit

// A couple of overlapping circles to play with
let frames = [
    CGRect(x: 100, y: 100, width: 200, height: 200),
    CGRect(x: 50, y: 50, width: 200, height: 200)
]

let blurView = UIImageView(image: ...) // <== You can drag an image here. Literals are cool.

let size = blurView.bounds.size
let scale = UIScreen.mainScreen().scale

// First, create a bitmap context to work in.
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue)
let ctx = CGBitmapContextCreate(nil, Int(size.width*scale), Int(size.height*scale),
8, 4 * Int(size.width * scale), CGColorSpaceCreateDeviceRGB(), bitmapInfo.rawValue)
CGContextScaleCTM(ctx, scale, scale)

// iOS draws upsidedown from Core Graphics, so you'll probably want to flip your context:
CGContextConcatCTM(ctx, CGAffineTransformMake(1, 0, 0, -1, 0, size.height))

// Everything we want to draw should be opaque
// Everything we want to clip should be translucent

CGContextSetGrayFillColor(ctx, 1, 1) // white
CGContextFillRect(ctx, blurView.bounds)

// And now we clear all our circles
CGContextSetBlendMode(ctx, .Clear)
CGContextSetGrayFillColor(ctx, 1, 0) // clear
for f in frames {
    CGContextFillEllipseInRect(ctx, f)
}

// Make the masking image
let maskImage = CGBitmapContextCreateImage(ctx)

// For your playground amusement (you can quicklook this line)
UIImage(CGImage: maskImage)

// Create the masking layer
let mask = CALayer()
mask.frame = blurView.layer.frame
mask.contents = maskImage

// And apply it
blurView.layer.mask = mask

// And the final so you can quicklook it
blurView

enter image description here

关于ios - 组合重叠的 UIBezierPaths 以创建单个蒙版,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34030296/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4