How to call a function passing an arbitrary enum

I am trying to write a reusable selector control.

I want to pass it any enum type where the enum is of the form
enum XXX: String, CaseIterable
and return a binding to the selected enum value. I need to access the raw values of the enum to act as item labels.

i.e., my use case looks something like:

enum Choices: String, CaseIterable {
case first: "First"
case second: "Second"
...
}

I want to build a control view, initialized with a prompt string, an enumeration type that meets the above requirements and a @Binding to an instance of this enum (used as both an initial value and a selection result).

The reusability of this control depends on being able to use it with any suitable enum. (For type safety, it should not compile if the enum is not suitable.)

I can write

struct Selector<E: CaseIterable>: View {
let prompt: String,
let choices: [E]
@Binding var selection: E

init(prompt: String, choices: E.Type, selection: Binding<E>) {
    self.prompt = prompt
    self.choices = choices.allCases as! [E]
    self._selection = selection
}

var body: some View {
        ...
}

}

but I get a compiler error (Value of type 'E' has no member 'rawValue') when I attempt to access the raw value string.

I don't understand how to express this requirement. Can you help?

Your snippet does not display your problem. Please resnip.

In the meantime, you can simplify. You don't need to store that static property.

import SwiftUI

struct Selector<E: CaseIterable & RawRepresentable<String>>: View
where E.AllCases == [E] {
  let prompt: String
  var choices: [E] { E.allCases }
  @Binding var selection: E

  init(prompt: String, selection: Binding<E>) {
    self.prompt = prompt
    self._selection = selection
    print(selection.wrappedValue.rawValue) // ????
  }

  var body: some View { EmptyView() }
}

Indeed, you didn't show the error...

Assuming you want to do something like this:

    var body: some View {
        let s: String = choices.first!.rawValue
        Text("xx")
    }

the fix could be:

struct Selector<E: CaseIterable & RawRepresentable>: View where E.RawValue == String {
2 Likes

Danny and tera,

Thank you both. Your insights and suggestions enabled me to solve my problem in an elegant fashion. I rally appreciate your thoughtful responses.

Rick Aurbach

3 Likes