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

SwiftUI 2.0如何给视图添加带镂空遮罩的模糊效果且不使用UIViewRepresentable

SwiftUI 2.0(iOS14+)纯原生实现带镂空的新手引导模糊蒙层方案

可以实现,完全不需要借助UIViewRepresentable,仅用SwiftUI 2.0原生API即可完成,最低兼容iOS14,且支持全局复用,不需要拆分原有视图层级里的高亮元素。

实现核心逻辑

利用blur()修饰符+mask()反向路径裁剪的组合,让模糊效果和半透明蒙层仅作用在非镂空区域,镂空位置直接透出下层未经处理的原始视图,自然不会被模糊或蒙层覆盖。

完整代码实现

1. 可复用的新手引导修饰符

import SwiftUI

// 新手引导蒙层修饰符
struct CoachMarkModifier: ViewModifier {
    // 镂空区域的frame(全局坐标系)
    let hollowRect: CGRect
    // 模糊半径
    let blurRadius: CGFloat = 5
    // 半透蒙层透明度
    let maskOpacity: Double = 0.3
    // 镂空区域圆角
    let hollowCornerRadius: CGFloat = 8
    
    func body(content: Content) -> some View {
        content
            .overlay(
                // 模糊层+蒙层组合
                content
                    .blur(radius: blurRadius)
                    .overlay(
                        Color.black.opacity(maskOpacity)
                    )
                    // 反向裁剪,挖掉镂空区域
                    .mask(
                        Path { path in
                            path.addRect(UIScreen.main.bounds)
                            path.addRoundedRect(in: hollowRect, cornerSize: .init(width: hollowCornerRadius, height: hollowCornerRadius))
                        }
                        .fill(style: .init(eoFill: true))
                    )
            )
    }
}

// 扩展View简化调用
extension View {
    func addCoachMark(hollowRect: CGRect) -> some View {
        self.modifier(CoachMarkModifier(hollowRect: hollowRect))
    }
}

2. 无侵入获取高亮元素坐标(不需要拆分原视图)

通过PreferenceKey获取需要高亮的元素的全局坐标,不需要修改原有视图层级:

// 用于获取视图frame的PreferenceKey
struct HollowRectPreferenceKey: PreferenceKey {
    static var defaultValue: CGRect = .zero
    static func reduce(value: inout CGRect, nextValue: () -> CGRect) {
        value = nextValue()
    }
}

3. 使用示例

struct DemoView: View {
    @State private var hollowRect: CGRect = .zero
    
    var body: some View {
        VStack(spacing: 30) {
            // 原有层级内的高亮元素,无需拆分
            Image(systemName: "flag")
                .font(.system(size: 40))
                .foregroundColor(.red)
                // 仅需加一行修饰符获取自身全局坐标
                .background(
                    GeometryReader { geo in
                        Color.clear
                            .preference(key: HollowRectPreferenceKey.self, value: geo.frame(in: .global))
                    }
                )
            
            Text("其他页面内容")
            Button("普通操作按钮") {}
        }
        // 接收高亮元素的坐标
        .onPreferenceChange(HollowRectPreferenceKey.self, perform: { value in
            hollowRect = value
        })
        // 挂载新手引导效果
        .addCoachMark(hollowRect: hollowRect)
    }
}

扩展说明

  • 如需支持多个镂空区域,只需在mask的Path内多次添加挖空路径即可
  • 支持圆形、异形等任意形状的镂空,仅需修改Path的生成逻辑
  • 完全不侵入原有视图层级,全局复用性符合需求

内容的提问来源于stack exchange,提问作者I. Pedan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:24:04