You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将UIView作为另一个UIView的反向遮罩?

实现任意UIView作为反向遮罩的可行方案

要实现用任意UIView作为反向遮罩(即目标视图仅在遮罩视图的不可见区域显示),有两种实用方案,分别适配动态和静态场景:

方案1:基于图层混合模式(动态实时更新)

这种方案利用Core Animation的混合模式,直接通过视图层级实现反向遮罩,支持遮罩视图的动态变化(比如动画、子视图更新),无需手动刷新。

代码示例

// 1. 创建目标视图(示例为红色矩形)
let targetView = UIView(frame: CGRect(x: 40, y: 40, width: 200, height: 200))
targetView.backgroundColor = .red
view.addSubview(targetView)

// 2. 创建任意遮罩视图(示例为带圆角的绿色圆形,可替换为任何UIView)
let maskView = UIView(frame: CGRect(x: 90, y: 90, width: 100, height: 100))
maskView.backgroundColor = .green
maskView.layer.cornerRadius = 50

// 3. 创建容器视图,将目标视图和遮罩视图放入其中
let containerView = UIView(frame: targetView.frame)
containerView.addSubview(targetView)
containerView.addSubview(maskView)
view.addSubview(containerView)

// 4. 设置混合模式,实现反向遮罩
maskView.layer.compositingFilter = "destinationOut"
// 必须关闭组透明度,避免出现异常黑色背景
containerView.layer.allowsGroupOpacity = false

原理说明

  • destinationOut混合模式会让遮罩视图所在区域的目标视图内容被清除(镂空),保留遮罩视图以外的区域。
  • 关闭allowsGroupOpacity是为了防止容器视图的透明度设置干扰混合效果,确保镂空区域完全透明。

方案2:基于快照反向生成遮罩图层(静态场景)

如果遮罩视图是静态的(不会动态变化),可以将遮罩视图的快照转换为反向alpha通道的图片,再作为目标视图的mask图层使用。

代码示例

extension UIView {
    /// 给当前视图应用任意UIView作为反向遮罩
    func applyReverseMask(_ maskView: UIView) {
        // 获取遮罩视图的实时快照
        guard let snapshot = maskView.snapshotView(afterScreenUpdates: true) else { return }
        
        // 创建图片上下文,生成反向alpha的遮罩图片
        UIGraphicsBeginImageContextWithOptions(maskView.bounds.size, false, UIScreen.main.scale)
        snapshot.draw(at: .zero)
        // 反转alpha通道:清除原遮罩可见区域的alpha
        if let context = UIGraphicsGetCurrentContext() {
            context.setBlendMode(.destinationOut)
            UIRectFill(maskView.bounds)
        }
        let reversedMaskImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        // 创建遮罩图层并应用到目标视图
        let maskLayer = CALayer()
        maskLayer.contents = reversedMaskImage?.cgImage
        maskLayer.frame = self.bounds
        self.layer.mask = maskLayer
    }
}

// 使用示例
targetView.applyReverseMask(maskView)

原理说明

  • 通过snapshotView获取遮罩视图的视觉快照,然后在图片上下文中用destinationOut混合模式清除原遮罩的可见区域,生成反向alpha的图片。
  • 将该图片作为目标视图的layer.mask,即可实现反向遮罩效果。

内容的提问来源于stack exchange,提问作者Andrei Herford

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 21:21:48