2

Let's say I have a struct:

var topMenu: [TopMenu] = [TopMenu(name: "Menu", index: 1),
                      TopMenu(name: "Search", index: 2),
                      TopMenu(name: "Profile", index: 3),
                      TopMenu(name: "Settings", index: 4)]

This struct contains a string and an index, so I can create a menu based on a HStack and a ForEach with this elements. This is fine. But what I'm trying to do now is the following:

Let's say this struct is dynamic: I can have 3 elements but I can also have 5/6 elements (based on a backend call). And I would like to render a different view for each of this element (on click). At the moment i'm doing this with a simple if based on our index:

if self.index == 1 {
      First()
} else if self.index == 2 {
      Second()
} else if self.index == 3 {
      Third()
} else {
      First()
}

But this is not the best approach if I have more elements etc ...

My thought are the following, but I don't know what is the best approach for this:

  • Create a funcion that returns Any View based on the index and give for each view a default name so I can iterate on? For example View1, View2 etc?

  • Add something particular to my struct?

P.s. I would also like to do this in the safer way possible, I don't want crash etc! =)

Thank you!

1 Answer 1

5

Here is possible approach in SwiftUI 2.0 (in SwiftUI 1.0 ViewBuilder does not support yet switch, so if/else is the only way, but you can wrap it in enum as well).

enum Choices: Int {
    case menu = 1
    case search = 2
    case profile = 3
    case settings = 4

    @ViewBuilder
    func view() -> some View {
        switch self {
            case menu:
                MenuView()
            case search:
                SearchView()
            case profile:
                ProfileView()
            case settings:
                SettingsView()
        }
    }
}

struct DemoChoicesUsage: View {
    @State var index = 1
    var body: some View {
        VStack {
            (Choices(rawValue: index) ?? Choices.menu).view()
        }
    }
}

Also, optionally, you can modify also TopMenu to be linked directly to enum cases instead of indexes, like TopMenu(name: "Menu", tag: .menu)

struct TopMenu {
  let name: String
  let tag: Choices
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you very much for your answer! This is nice, but I'm still missing something from my question: What if (after a backend call) I find out that there are let's say 6 view insted of four? I need something even more dynamic I guess! Or is it my question weird?
It does not matter how many views - you need anyway to declare them and to create them somewhere.
Ok this is correct. So I put a limit, let say max 6 view, and I create all of them. And I render the ones I need only. May I ask, how do I use this fantastic enum? I mean, at the moment I have the if statement inside a VStack that containts the HStack with our menu,search,settings (with index) etc. But when I click in one of this how do I use the enum to render the correct view?
thank you man, I really appreaciate, this is what I was looking for.
Is it possible we are missing something? I just tested the code and with a simple check like (Choices.menu).view() to see if it works, nothing happened
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.