ios 如何使用UIView作为另一个UIView的反转掩码?

k10s72fa  于 2023-04-13  发布在  iOS
关注(0)|答案(1)|浏览(133)

UIView作为掩码应用到另一个UIView没有问题。

let view = UIView(...) 
let mask = UIView(...) 
view.mask = mask

现在只有view的那些部分可见,而mask视图也可见。**但是,如何将其反转?**我希望view可见,而mask**不可见。我如何做到这一点?
虽然我找到了几个解决方案来反转基于路径的蒙版(使用CAShapeLayer)或反转图像,但这不是我要找的。我不想反转路径蒙版或图像,而是视图蒙版。
假设view是一个红色矩形,mask是一个绿色的圆。将mask应用到view将得到一个红色的圆。然而,我想创建一个红色矩形,其中有一个圆洞。

再次强调:创建一个圆形路径并将其应用为遮罩是没有问题的。我不是在寻找路径遮罩(反转或不反转),而是寻找一个使用任何UIView作为反转遮罩的解决方案。

这可能吗?

6psbrbz9

6psbrbz91#

这在一定程度上取决于您所指的 “any UIView“inverted”
例如,如果这是anyView

什么是*倒置
让我们假设你正在谈论一个UIView,它有一个clear的背景,包含一些子视图和一些形状等。
因此,如果我们设置一个包含大量大文本的标签,它将位于我们的视图后面:

然后添加一个我们想要屏蔽的图像视图,我们的anyView,以及另一个具有清晰背景的anyView副本,以便我们可以看到我们正在做的事情:

我们可以做的是将anyView渲染为UIImagerenderedImage),然后用纯色创建另一个UIImage(可以是任何纯色,我在这个例子中使用了.systemGreen),然后用blendMode: .destinationOut渲染renderedImage,得到以下内容:

然后我们将使用该图像创建一个新的UIImageView,并使用that作为掩码:

func mask(someView: UIView, withView: UIView) {
    
    // make sure the background of the view we're going to use
    //  as the mask is clear
    let bkgColor = withView.backgroundColor
    withView.backgroundColor = .clear
    
    let sz = withView.bounds.size
    
    let renderer = UIGraphicsImageRenderer(size: sz)
    
    let renderedImage = renderer.image { rendererContext in
        withView.drawHierarchy(in: withView.bounds, afterScreenUpdates: true)
    }
    
    let invertedImage = renderer.image { rendererContext in
        UIColor.systemGreen.setFill()
        UIRectFill(.init(origin: .zero, size: renderedImage.size))
        renderedImage.draw(at: .zero, blendMode: .destinationOut, alpha: 1.0)
    }
    
    tempImageView.image = invertedImage
    
    // create a new image view to use as a mask
    let newMaskView = UIImageView(frame: someView.bounds)
    newMaskView.image = invertedImage
    someView.mask = newMaskView
    
    // reset the mask source view's background
    withView.backgroundColor = bkgColor
    
}

给我们这个结果:

相关问题