swiftui

How to return different Views from switch case


I have this function in my SwiftUI code

func getShape(shape:Int, i: Int) -> some View {
    switch self.selectedShape {
    case 0:
        return Rectangle()
               .stroke(Color.pink)
               .frame(width: 150, height: 150)
               .position(CGPoint(x: scrCenterX, y: scrCenterY))
               .rotationEffect(Angle(degrees: Double(i) * Double(self.angleStep)))
    case 1:
        return Circle()
               .stroke(Color.pink)
               .frame(width: 150, height: 150)
               .position(CGPoint(x: scrCenterX, y: scrCenterY))
            .rotationEffect(Angle(degrees: Double(i) * Double(self.angleStep)))
    case 2:
        return Capsule()
               .stroke(Color.pink)
               .frame(width: 150, height: 150)
               .position(CGPoint(x: scrCenterX, y: scrCenterY))
            .rotationEffect(Angle(degrees: Double(i) * Double(self.angleStep)))
    default:
        return Rectangle()
        .stroke(Color.pink)
        .frame(width: 150, height: 150)
        .position(CGPoint(x: scrCenterX, y: scrCenterY))
            .rotationEffect(Angle(degrees: Double(i) * Double(self.angleStep)))
    }
}

and compliler says that "Function declares an opaque return type, but the return statements in its body do not have matching underlying types". If I change in all "cases" shape to e.g. Circle then code is compiled without any error. How I cold achieve returning shape based on selectedShape value? Thanks.


Solution

  • some View is an Opaque (to the caller) return type that is some type that conforms to View. But it has to be a specific type known at compile-time to the callee.

    So, at compile-time, you need to decide which concrete type conforming to View it's going to be. It cannot be either Rectangle or Circle; it always needs to be the same type. So what you're trying to do is not possible (by design) with opaque types.

    Instead, you would need to type erase into AnyView:

    func getShape(shape:Int, i: Int) -> AnyView {
    
       switch self.selectedShape {
       case 0: return AnyView(Rectangle()
                              .stroke(Color.pink)
                              .frame (...)
                              )
       case 1: return AnyView(Circle()
                              .stroke(Color.pink)
                              .frame (...)
                              )
       // etc...
    }