菜鸟教程小白 发表于 2022-12-12 17:29:29

ios - 组合重叠的 UIBezierPaths 以创建单个蒙版


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

<pre><code>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
</code></pre>

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

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

<p> <a href="/image/fr1U7.png" rel="noreferrer noopener nofollow"><img src="/image/fr1U7.png" alt="screenshot"/></a> </p>

<p>有什么办法解决吗?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>基本思想是用不透明的颜色填充位图上下文,然后清除我们想要剪辑的任何内容。抓取该位图上下文的图像并用作蒙版。</p>

<p>如果您愿意,可以将其复制到 Playground :</p>

<pre><code>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: ...) // &lt;== 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&#39;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
</code></pre>

<p> <a href="/image/6eY5D.png" rel="noreferrer noopener nofollow"><img src="/image/6eY5D.png" alt="enter image description here"/></a> </p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 组合重叠的 UIBezierPaths 以创建单个蒙版,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/34030296/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/34030296/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 组合重叠的 UIBezierPaths 以创建单个蒙版