SwiftUI 在圆角矩形内屏蔽一个矩形

SwiftUI Mask a rectangle inside a rounded rectangle

你好。我想知道,在 SwiftUI 中,您如何屏蔽圆角矩形的内容,以便子矩形剪裁角。

在我的示例中,我在 zstack 上有一个白色圆角矩形和一个粉红色矩形,我尝试应用剪裁,但粉红色矩形不符合角。

我试过将 .mask 应用于白色矩形,但它给出了与预期不同的结果(有时它不显示粉红色矩形)。

我确实找到了一个示例,您可以在其中设置自己的 cornerRadius

但我想知道是否有办法屏蔽粉红色矩形的 internals/body 以使其符合父级的圆角矩形?

我的代码如下;

var body: some View {
        GeometryReader { geometry in

            Color.gray
                .edgesIgnoringSafeArea(.top)
                .overlay(

                    ZStack (alignment: .topLeading) {

                        RoundedRectangle(cornerRadius: 16,
                                         style: .continuous)
                            .foregroundColor(.white)
                            .shadow(radius: 10)
                             // Tried using .mask here 

                        Rectangle()
                            .fill(Color.pink)
                            .frame(minWidth: 0, maxWidth: .infinity, maxHeight: 150, alignment: .top)
                            .clipped()


                    }
                    .frame(width: 300, height: 450, alignment: .center)
            )

        }
        .edgesIgnoringSafeArea(.all)
    }

编辑:澄清:

粉红色矩形应保持为矩形,但剪裁左上角和右上角以匹配父级白色圆角矩形。

如果我正确理解了您的目标,这里有一个解决方案 - 正确位置唯一需要的剪辑是构建内部内容(在本例中为两个矩形)之后。所以用 RoundedRectangle 剪裁会在整个卡片周围形成圆角。 (以及 shadow 很可能是整张卡片所需要的,所以放在最后)。

更新:用 Xcode 13.3 / iOS 15.4

重新测试

ZStack (alignment: .topLeading) {
    Rectangle()
        .foregroundColor(.white)

    Rectangle()
        .fill(Color.pink)
        .frame(minWidth: 0, maxWidth: .infinity, maxHeight: 150, alignment: .top)
}
.clipShape(RoundedRectangle(cornerRadius: 16))       // << here !!
.frame(width: 300, height: 450, alignment: .center)
.shadow(radius: 10)

backup

看看这个

struct ContentView: View {
    var body: some View {
        GeometryReader { geometry in

            Color.gray
                .edgesIgnoringSafeArea(.top)
                .overlay(

                    ZStack (alignment: .topLeading) {

                        RoundedRectangle(cornerRadius: 16,
                                         style: .continuous)
                            .foregroundColor(.white)
                            .shadow(radius: 10)
                        // Tried using .mask here

                        Rectangle()
                            .fill(Color.pink)
                            .frame(minWidth: 0, maxWidth: .infinity, maxHeight: 150, alignment: .top)
                            .clipShape(RoundedRectangle(cornerRadius: 16)) // <<<<<<


                    }
                    .frame(width: 300, height: 450, alignment: .center)
            )

        }
        .edgesIgnoringSafeArea(.all)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

@Asperi 已经发布了一个很好的答案,我也通过在 SwiftUI 中使用 mask 修饰符来做到这一点。此外,您只需设置一次 cornerRadius

VStack(spacing: 0)
{
    ZStack(alignment: .center)
    {
       Rectangle()
       .fill(Color.red)
       .frame(width: 66, height: 20)

    }


    ZStack(alignment: .center)
    {
       Rectangle()
       .fill(Color.white)
       .frame(width: 66, height: 46)

    }
}
.mask(Rectangle()
        .cornerRadius(3.0)
        .frame(width: 66, height: 66)
)

我认为更简单的方法是将 cornerradius 应用于 ZStack

ZStack (alignment: .topLeading) {

    RoundedRectangle(cornerRadius: 16,
                 style: .continuous)
        .foregroundColor(.white)
        .shadow(radius: 10)
         // Tried using .mask here

    Rectangle()
       .fill(Color.pink)
       .frame(minWidth: 0, maxWidth: .infinity, maxHeight: 150, alignment: .top)
        //.clipped() //<<= here
}
.frame(width: 300, height: 450, alignment: .center)
.cornerRadius(20) //<<= here