Flatten TupleViews using SwiftUI

2020-03-26 03:27发布

问题:

Ok, SwiftUI was released this week so we're all n00bs but... I have the following test code:

var body: some View {
    switch shape {
    case .oneCircle:
        return ZStack {
            Circle().fill(Color.red)
        }
    case .twoCircles:
        return ZStack {
            Circle().fill(Color.green)
            Circle().fill(Color.blue)
        }
    }
}

which produces the following error:

Function declares an opaque return type, but the return statements in its body do not have matching underlying types

This happens because the first ZStack is this type:

ZStack<ShapeView<Circle, Color>>

and the second is this type:

ZStack<TupleView<(ShapeView<Circle, Color>, ShapeView<Circle, Color>)>>

How do I deal with this in SwiftUI? Can they be flattened somehow or be made to conform to the same type.

回答1:

One way to fix this is to use the type eraser AnyView:

var body: some View {
    switch shape {
    case .oneCircle:
        return AnyView(ZStack {
            Circle().fill(Color.red)
        })
    case .twoCircles:
        return AnyView(ZStack {
            Circle().fill(Color.green)
            Circle().fill(Color.blue)
        })
    }
}


回答2:

You can also use Group which is logical container so won't change anything visual.

 var body: some View {
    Group {
     switch shape {
     case .oneCircle:
        return ZStack {
            Circle().fill(Color.red)
        }
     case .twoCircles:
        return ZStack {
            Circle().fill(Color.green)
            Circle().fill(Color.blue)
        }
     }
    }
}