How to make different clipShape?

@State private var flipped = false
    
    let x: CGFloat = 0
    let y: CGFloat = 1
    let z: CGFloat = 0

    var body: some View {
        VStack {
            ZStack {
                Rectangle()
                    .frame(width: 100, height: 100)
                    .foregroundColor(.yellow)
                    .clipShape(flipped ? Capsule() : Rectangle())
            }
            .rotation3DEffect(.degrees(flipped ? -180 : 0), axis: (x, y, z))
            .onTapGesture {
                withAnimation() {
                    self.flipped.toggle()
                }
            }
        }
    }

Your problem is that the clipShape modifier wants a concrete implementation of the Shape protocol. While Capsule and Rectangle both conform to Shape, they are different types and don't have a common concrete supertype that conforms to Shape.

You can work around this by creating your own concrete Shape type that can wrap a Capsule or a Rectangle, like this:

struct AnyShape: Shape {
    init<S: Shape>(_ wrapped: S) {
        _path = { rect in
            print("rect=\(rect)")
            let path = wrapped.path(in: rect)
            print("path=\(path)")
            return path
        }
    }

    func path(in rect: CGRect) -> Path {
        return _path(rect)
    }

    private let _path: (CGRect) -> Path
}

And then use it like this:

.clipShape(flipped ? AnyShape(Capsule()) : AnyShape(Rectangle()))

I tested this successfully in a playground in Xcode 11 beta 4. When I tried it in a playground in Xcode 11 beta 5, the playground crashed. I filed FB6864021.

1 Like

I think the Xcode 11 beta 5 crash is probably due to this problem mentioned in the release notes:

  • Using the Path structure may cause your app to crash if you’re using the SDKs included in Xcode 11 beta 5. As a result, you may be unable to successfully follow the steps in the Drawing Paths and Shapes tutorial. (53523206)

@mayoff Thanks, great solution. I tried it on the simulator in Xcode 11 beta 5, the app crashed. I am downloading Xcode 11 beta 4 and retest.

SwiftUI is generally off-topic here, and it would be better to ask these questions on the Apple developer forums.

It's really about "Using Swift" to do SwiftUI. Solving the problem require some advance knowledge about Swift language feature and you only find people with this kind of skill here.

If he is asking how to make SwiftUI show red color, then I agree you send them somewhere else. But this is about Swift, let this kind of post stay, please..

1 Like