kittonian
kittonian

Reputation: 1421

SwiftUI - Pass Enum as Parameter to View

I have an environment object (we'll call it sample for this example) with multiple enums inside. I have a view that I would like to use over and over again instead of duplicating it a bunch of times. Inside that view is a button where I want to set the value of one of the enums.

I'm trying to figure out how to pass that button action as a parameter of the call to the view like this, TestView(enum: sample.enum1, destination: .main)

Here's some code:

class Sample: ObservableObject {

    @Published var enum1: Enum1 = .main
    @Published var enum2: Enum2 = .foo
    @Published var enum3: Enum3 = .add

    enum Enum1 {
        case main
        case test
    }

    enum Enum2 {
        case foo
        case blah
    }

    enum Enum3 {
        case add
        case remove
    }
}

struct MultipleUseView: View {
    @EnvironmentObject var sample: Sample
    @State var enum: Sample
    @State var destination: Sample

    var body: some View {
        Button {
            enum = destination
        } label: {
            "Tap Me"
        }
    }
}

struct TestView: View {
    @EnvironmentObject var sample: Sample

    var body: some View {
        MultipleUseView(enum: sample.enum1, destination: .main)
    }
}

The two @State variables I included in my sample code are just to show what's not working at the moment. All I need to figure out is how to pass those parameters to MultipleUseView, from TestView, so that the button in MultipleUseView ends up with an action of:

sample.enum1 = .main

Upvotes: 1

Views: 1267

Answers (1)

Asperi
Asperi

Reputation: 257563

With pretty amount of doubts I would suppose that you want to write a value into environment object by key path... if I'm right then it can be done as follows

struct MultipleUseView<T>: View {
    @EnvironmentObject var sample: Sample

    // bad practice to name vars as keywords, but if you insist...
    var `enum`: ReferenceWritableKeyPath<Sample, T>
    var destination: T

    var body: some View {
        Button {
            sample[keyPath: `enum`] = destination // << here !!
        } label: {
            Text("Tap Me")
        }
    }
}

struct TestView: View {
    @EnvironmentObject var sample: Sample

    var body: some View {
        MultipleUseView(enum: \.enum1, destination: .main)
    }
}

Upvotes: 1

Related Questions