如何在SwiftUI中创建一个透明的矩形

14

我想通过一个小矩形将图像变为100%透明,并使其在其他地方50%透明。就像制作一个小孔来透过小矩形看到外面。以下是我的代码...

struct ImageScope: View {

    var body: some View {
        ZStack {
            Image("test_pic")

            Rectangle()
                .foregroundColor(Color.black.opacity(0.5))

            Rectangle()
                .frame(width: 200, height: 150)
                .foregroundColor(Color.orange.opacity(0.0))
                .overlay(RoundedRectangle(cornerRadius: 3).stroke(Color.white, lineWidth: 3))
        }
    }
}
为了更容易理解...

在此输入图片描述

3个回答

15

这是一种可行的方法。它使用自定义形状和奇偶填充样式。

已经在Xcode 11.4 / iOS 13.4上测试通过。

下面的演示具有更高的透明度对比度,以获得更好的可见性。

演示

struct Window: Shape {
    let size: CGSize
    func path(in rect: CGRect) -> Path {
        var path = Rectangle().path(in: rect)

        let origin = CGPoint(x: rect.midX - size.width / 2, y: rect.midY - size.height / 2)
        path.addRect(CGRect(origin: origin, size: size))
        return path
    }
}

struct ImageScope: View {

    var body: some View {
        ZStack {
            Image("test_pic")

            Rectangle()
                .foregroundColor(Color.black.opacity(0.5))
                .mask(Window(size: CGSize(width: 200, height: 150)).fill(style: FillStyle(eoFill: true)))

            RoundedRectangle(cornerRadius: 3).stroke(Color.white, lineWidth: 3)
                .frame(width: 200, height: 150)
        }
    }
}

5

使用blendMode(.destinationOut),您无需绘制自定义形状,仅需一行代码即可。有时需要添加.compositingGroup()修饰符。

ZStack {
    Color.black.opacity(0.5)
    Rectangle()
        .frame(width: 200, height: 200)
        .blendMode(.destinationOut) // << here
}
.compositingGroup()

2
我尝试了这个方法和几个变化,但是无法使其工作。我认为这个答案需要更多的解释和/或代码(使用图像)。 - Marcy
2
@Marcy 请尝试在 ZStack 上添加 .compositingGroup() 修改器。 - eja08

3
为了清晰起见,此解决方案基于eja08的答案,但使用图像完全展开。混合模式.destinationOut在黑色矩形中创建切口。嵌套的ZStack将图像放置在背景中,不受混合模式的影响。
struct ImageScope: View {

    var body: some View {
        ZStack {
            Image("test_pic")
            ZStack {
                Rectangle()
                    .foregroundColor(.black.opacity(0.5))
                Rectangle()
                    .frame(width: 200, height: 150)
                    .blendMode(.destinationOut)
                    .overlay(RoundedRectangle(cornerRadius: 3).stroke(.white, lineWidth: 3))
            }
            .compositingGroup()
        }
    }
}

结果如下:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接