Roman
Roman

Reputation: 839

SwiftUI doesn't like switch?

Trying to following this discussion, I implemented the suggestion of Yurii Kotov:

struct ContentView: View {

@State private var index = 0

@ViewBuilder
 var body: some View {
   if index == 0 {
       MainView()
   } else {
       LoginView()
   }
}

It works fine. But if I try to use a switch statement instead:

    switch  index {
        case 0: MainView()
        case 1: LoginView()
        default:
            print("# error in switch")
        }

nothing happens. There is no mistake alert, but also no result at all. Could somebody help?

Upvotes: 2

Views: 4639

Answers (2)

Jacksonsox
Jacksonsox

Reputation: 1233

I had an issue with the default case where I wanted a "break" type situation for the switch to be exhaustive. SwiftUI requires some type of view, I found that

EmptyView() solved the issue.

also noted here EmptyView Discussion that you "have to return something"

struct FigureListMenuItems: View {
    var showContextType: ShowContextEnum
    @Binding var isFavoriteSeries: Bool?

    var body: some View {
    
        Menu {
            switch showContextType {
            case .series:
                Button(action: { toggleFavoriteSeries() }) {
                    isFavoriteSeries! ?
                    Label("Favorite Series?", systemImage: "star.fill")
                        .foregroundColor(.yellow)
                    :
                    Label("Favorite Series?", systemImage: "star")
                        .foregroundColor(.yellow)
                }
            default: // <-- can use EmptyView() in this default too if you want
                Button(action: {}) {
                    Text("No menu items")
                }
            }
        } label: {
            switch showContextType {
            case .series:
                isFavoriteSeries! ?
                Image(systemName: "star.fill")
                    .foregroundColor(.yellow)
                :
                Image(systemName: "star")
                    .foregroundColor(.yellow)
            default:
                EmptyView()
            }
            Label("Menu", systemImage: "ellipsis.circle")
        }
    }

    private func toggleFavoriteSeries() {
        isFavoriteSeries?.toggle()
    }
}

Enum for switch

enum ShowContextEnum: Int {
    case series = 1
    case whatIsNew = 2
    case allFigures = 3
}

Upvotes: 8

Hrabovskyi Oleksandr
Hrabovskyi Oleksandr

Reputation: 3275

As @Sweeper said: your if...else and switch...case statements are not equal. The main idea is: body is just a computed variable of a View protocol and it should return something of its' type. Sure, you can do it with switch...case statements. In your code snippet mistake is in default statement: body cannot return() -> Void, only some View. So your code should looks like this:

struct ViewWithSwitchStatements: View {

    @State var option = 0

    var body: some View {

        switch option {
        case 1:
            return AnyView(Text("Option 1"))
        case 2:
            return AnyView(Text("Option 2"))
        default:
            return AnyView(Text("Wrong option!"))
        }

    }
}

However you can't put it into VStack or something else, like if...else statements.

Upvotes: 1

Related Questions