SwiftUI实现内部零透明度遮罩视图的技术咨询
SwiftUI 实现中间完全透明的遮罩视图
你的测试代码无法实现预期效果,原因是ZStack中两个矩形是叠加关系,上层的半透明黑色矩形会覆盖整个区域,下层的透明矩形仅自身不可见,无法挖空上层内容。以下是两种可行的实现方案:
方案一:自定义镂空Shape
通过自定义Shape,利用路径减法创建带镂空的遮罩:
// 自定义带镂空的矩形Shape struct HollowRectangle: Shape { func path(in rect: CGRect) -> Path { let outerPath = Path(rect) // 定义中间200x100的镂空区域,居中放置 let innerRect = CGRect( x: rect.midX - 100, y: rect.midY - 50, width: 200, height: 100 ) let innerPath = Path(innerRect) // 用外层路径减去内层路径,得到镂空效果 return outerPath.subtracting(innerPath) } } struct TestView: View { var body: some View { ZStack{ Image("bigpancake") .resizable() .scaledToFill() .frame(maxWidth: .infinity, maxHeight: .infinity) .clipped() // 防止图片超出视图边界 // 应用镂空遮罩,填充半透明黑色 HollowRectangle() .foregroundColor(.black.opacity(0.3)) } } }
方案二:利用混合模式(Blend Mode)
通过compositingGroup和blendMode实现挖空效果,无需自定义Shape:
struct TestView: View { var body: some View { ZStack{ Image("bigpancake") .resizable() .scaledToFill() .frame(maxWidth: .infinity, maxHeight: .infinity) .clipped() ZStack { // 全屏半透明黑色背景 Color.black.opacity(0.3) // 中间矩形,用混合模式清除对应区域的背景 Rectangle() .frame(width: 200, height: 100) .foregroundColor(.black) .blendMode(.destinationOut) } .compositingGroup() // 将ZStack内容合并为一个渲染组,确保混合模式生效 } } }
两种方案都能实现「中间区域完全透明、其余区域半透明黑色」的效果,可根据需求选择。
内容的提问来源于stack exchange,提问作者Qazi Ammar
相关产品推荐
相关产品推荐

