在 SwiftUI 中,如何用另一个视图剪辑视图的一部分?

ali*_*ego 3 xcode ios swiftui

我试图在 SwiftUI 中重叠两个圆圈并在它们之间留出边距。我目前正在使用这种方法:

ZStack {
    Circle()
        .frame(width: 60, height: 60)
        .foregroundColor(Color.blue)
        .shadow(color: .black.opacity(0.5), radius: 4, x: 2, y: 2)
    ZStack {
        Circle()
            .frame(width: 26, height: 26)
            .foregroundColor(Color(.systemGray5))
        Circle()
            .frame(width: 22, height: 22)
            .foregroundColor(.blue)
    }
    .offset(x: 26, y: 17)
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

问题是,由于大圆上的阴影,我永远无法完美匹配小圆边框圆上的背景(即 systemGray5。所以虽然它看起来不错,但我只希望边距出现在不是一直围绕着较小的圆圈。

在插画或其他方式中,我会用我的 26 大小的圆圈剪辑大图像,它看起来就像从中被咬了一口。那么我就可以完美的达到这个效果了。

有没有办法在 SwiftUI 中剪掉我的大圆的底部?

Asp*_*eri 7

这是使用倒置掩码的可能方法的演示(它经过简化,但想法应该很明确 - 删除硬编码和“咬”位置计算由您负责)。

使用 Xcode 13.2 / iOS 15.2 进行测试

演示

struct DemoView: View {
    struct BiteCircle: Shape {
        func path(in rect: CGRect) -> Path {
            let offset = rect.maxX - 26
            let crect = CGRect(origin: .zero, size: CGSize(width: 26, height: 26)).offsetBy(dx: offset, dy: offset)

            var path = Rectangle().path(in: rect)
            path.addPath(Circle().path(in: crect))
            return path
        }
    }
    var body: some View {
        ZStack {
            Circle()
                .frame(width: 60, height: 60)
                .foregroundColor(Color.blue)
                .mask(BiteCircle().fill(style: .init(eoFill: true)))     // << here !!
                .shadow(color: .black.opacity(0.5), radius: 4, x: 2, y: 2)

            Circle()
                .frame(width: 22, height: 22)
                .foregroundColor(.blue)
                .offset(x: 18, y: 18)
        }

    }
}
Run Code Online (Sandbox Code Playgroud)