skip to Main Content

How can I present in swiftUI a view in a switch case?

import Foundation

enum SideMenuViewModel: Int, CaseIterable, Decodable {
    case Home
    case Users
    case TODOs
    case AboutUs
    
    var title: String {
        switch self {
        case .Home: return "Home"
        case .Users: return "Users"
        case .TODOs: return "TODOs"
        case .AboutUs: return "AboutUs"
        }
    
    }
    var imageName: String {
        switch self {
        case .Home: return "bookmark.circle"
        case .Users: return "person"
        case .TODOs: return "list.bullet"
        case .AboutUs: return "info.circle"
        }
    }
}

3

Answers


  1. You need view builder property, like

    @ViewBuilder var view: some View {
        switch self {
        case .Home:
           HomeView()
        case .Users:
           UsersView()
        case .TODOs:
           TODOView()
        case .AboutUs:
           AboutUsView()
        }
    }
    
    Login or Signup to reply.
  2. Instead of trying to return a View from an enum, inject the enum into your View and switch over the enum inside the view, then return the appropriate View from there.

    A ViewModel should be independent from its view type, only the view should know about the VM, not the other way around.

    struct SideMenuView: View {
      private let viewModel: SideMenuViewModel
    
      init(viewModel: SideMenuViewModel) {
        self.viewModel = viewModel
      }
    
      var body: some View {
        switch viewModel {
        case .AboutUs:
          AboutUsView(...)
        case .Home:
          HomeView(...)
          ...
        }
      }
    }
    
    Login or Signup to reply.
  3. I would suggest to craft an enum with associated values as follows:

    enum ViewState {
        case .home(HomeViewState)
        case .users(UsersViewState)
        case .todos(TodosViewState)
        case .aboutUs(AboutUsViewState)
    }
    

    So, each case has its own distinct "state" (aka model) for the respective view.

    struct HomeViewState {...}
    struct UsersViewState {...}
    struct TodosViewState {...}
    struct AboutUsViewState {...}
    

    In a parent view, obtain the enum value, then simply select the given state using a switch statement. Extract the view specific state and compose the view in the body:

    struct ContentView: View {
        let viewState: ViewState
    
        var body: some View {
            switch viewState {
            case .home(let state):
                HomeView(state: state)
            case .users(let state):
                UsersView(state: state)
            case .todos(let state):
                TodosView(state: state)
            case .aboutUs(let state):
                AboutUsView(state: state)
            }
        }
    }
    

    Example for the HomeView:

    struct HomeView: View {
        let state: HomeViewState
    
        var body: some View {
            ...
        }
    }
    

    Your Model:

    final class SideMenuViewModel: ObservableObject {
        @Published var viewState: ViewState = ...
        ... 
    }
    

    A root view in the scene my now subscribe to the SideMenuViewModel and pass the viewState to the ContentView.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search