SwiftUI 添加倒置遮罩 [英] SwiftUI add inverted mask

查看:33
本文介绍了SwiftUI 添加倒置遮罩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为两个形状添加遮罩,以便第二个形状遮住第一个形状.如果我执行诸如 Circle().mask(Circle().offset(…)) 之类的操作,则会产生相反的效果:防止第一个圆圈之外的任何内容可见.

I'm trying to add a mask to two shapes such that the second shape masks out the first shape. If I do something like Circle().mask(Circle().offset(…)), this has the opposite affect: preventing anything outside the first circle from being visible.

对于 UIView,答案在这里:iOS invert mask in drawRect

然而,试图在 SwiftUI 没有 UIView 中实现这一点让我望而却步.我尝试实现一个 InvertedShape,然后我可以将其用作掩码:

However, trying to implement this in SwiftUI without UIView eludes me. I tried implementing an InvertedShape with I could then use as a mask:

struct InvertedShape<OriginalType: Shape>: Shape {
    let originalShape: OriginalType

    func path(in rect: CGRect) -> Path {
        let mutableOriginal = originalShape.path(in: rect).cgPath.mutableCopy()!
        mutableOriginal.addPath(Path(rect).cgPath)
        return Path(mutableOriginal)
            .evenOddFillRule()
    }
}

不幸的是,SwiftUI 路径没有 addPath(Path)(因为它们是不可变的)或 evenOddFillRule().您可以访问路径的 CGPath 并制作可变副本,然后添加两个路径,但是,evenOddFillRule 需要在 CGLayer 上设置,而不是 CGPath.因此,除非我能进入 CGLayer,否则我不确定如何继续.

Unfortunately, SwiftUI paths do not have addPath(Path) (because they are immutable) or evenOddFillRule(). You can access the path's CGPath and make a mutable copy and then add the two paths, however, evenOddFillRule needs to be set on the CGLayer, not the CGPath. So unless I can get to the CGLayer, I'm unsure how to proceed.

这是 Swift 5.

This is Swift 5.

推荐答案

这里是创建倒置遮罩的可能方法的演示,仅通过 SwiftUI,(以在视图中打孔为例)

Here is a demo of possible approach of creating inverted mask, by SwiftUI only, (on example to make a hole in view)

func HoleShapeMask(in rect: CGRect) -> Path {
    var shape = Rectangle().path(in: rect)
    shape.addPath(Circle().path(in: rect))
    return shape
}

struct TestInvertedMask: View {

    let rect = CGRect(x: 0, y: 0, width: 300, height: 100)
    var body: some View {
        Rectangle()
            .fill(Color.blue)
            .frame(width: rect.width, height: rect.height)
            .mask(HoleShapeMask(in: rect).fill(style: FillStyle(eoFill: true)))
    }
}

这篇关于SwiftUI 添加倒置遮罩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆