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

I'm getting the following compiler error.


error: function declares an opaque return type, but the return statements in its body do not have matching underlying types
    var body: some View {
                        ^

I'm trying to switch on some state to determine what the rest of the view hierachy looks like. How do I do this in SwiftUI? Thanks!


enum Choices: Equatable, Hashable {
    case one
    case two
}

struct HeaderView: View {
    @State var choices = Choices.one
   
    var body: some View {
        switch choices {

        case .two:
            return ChoiceTwoView(choices: $choices)

        default:
            return ChoiceOneView(choices: $choices)
        }
    }
}

struct ChoiceOneView: View {
    @Binding var choices: Choices
   
    init(choices: Binding) {
        $choices = choices
    }
   
    var body: some View {
        VStack {
            HStack {
                Image(systemName: "person.icloud")
               
                VStack(alignment: .leading) {
                    Text("Person Name")
                        .font(.headline)
                   
                    Text("Some long long long long long long long long text")
                        .lineLimit(nil)
                        .multilineTextAlignment(.leading)
                }
            }
        }
    }
}

struct ChoiceTwoView: View {
   
    @Binding var choices: Choices
   
    init(choices: Binding) {
        $choices = choices
    }
   
    var body: some View {
        VStack {
            HStack {
                Image(systemName: "person.icloud")
               
                VStack(alignment: .leading) {
                    Text("Person Name")
                        .font(.headline)
                }
            }
        }
    }
}

Accepted Reply

Returning them as `AnyView` values seems like the solution:


struct HeaderView: View { 
    @State var choices = Choices.one 
    var body: some View { 
        switch choices { 
        case .two: 
            return AnyView(ChoiceTwoView(choices: $choices))
        default: 
            return AnyView(ChoiceOneView(choices: $choices))
        } 
    } 
}

Replies

To be sure, the compiler finds the error in HeaderView's body implementation:

error: swiftui.playground:22:25: error: function declares an opaque return type, but the return statements in its body do not have matching underlying types
    var body: some View {
                        ^

swiftui.playground:26:20: note: return statement has underlying type 'ChoiceTwoView'
            return ChoiceTwoView(choices: $choices)
                   ^

swiftui.playground:29:20: note: return statement has underlying type 'ChoiceOneView'
            return ChoiceOneView(choices: $choices)
                   ^

Returning them as `AnyView` values seems like the solution:


struct HeaderView: View { 
    @State var choices = Choices.one 
    var body: some View { 
        switch choices { 
        case .two: 
            return AnyView(ChoiceTwoView(choices: $choices))
        default: 
            return AnyView(ChoiceOneView(choices: $choices))
        } 
    } 
}

Why is it necessary to cast to AnyView?

AnyView works, but I think a @ViewBuilder is nicer.

https://developer.apple.com/documentation/swiftui/viewbuilder

Code Block
struct HeaderView: View {
@State var choices = Choices.one
@ViewBuilder
var body: some View {
switch choices {
case .two:
ChoiceTwoView(choices: choices)
default:
ChoiceOneView(choices: choices)
}
}
}

Note that there is no return statement.
  • Whoa, great call! Love this solution.

  • I believe this is the " Correct Solution for the mentioned problem" not the "AnyView" Thanks a lot

  • Wow, I have been looking for something like this for a long time :)

Add a Comment

I have covered opaque return here: https://medium.com/swift-blondie/opaque-return-type-in-swift-f5a8887c6be6