0

I have pretty much same question as here: SwiftUI Picker onChange or equivalent?, but .onChange won't solve it exactly I need.

I have wrote a question in that link, but I was told to ask a new question (as I wasn't able to find answer anywhere :(

I have this enum:

enum FruitTea: String, CustomStringConvertible, CaseIterable, Codable {
    case peach = "Peach"
    case passionFruit = "Passion Fruit"
    case mango = "Mango"
    case greenApple = "Green Apple"
    var description: String { rawValue }
            
}
    
enum TypeOfTea: String, CustomStringConvertible, CaseIterable, Codable {
    case specialTeaPresso = "Special Tea Presso"
    case teaLatte = "Tea Latte"
    case mousseSeries = "Mousse Series"
    case milkTea = "Milk Tea"
    case fruitTea = "Fruit Tea"
    var description: String { rawValue }
}

And this picker:

@State private var type: TypeOfTea = .specialTeaPresso
@State private var fruit: FruitTea = .passionFruit
Picker("Fruit Tea", selection: $fruit) {
    ForEach(FruitTea.allCases, id: \.self) {
        Text($0.rawValue).tag($0)
    }
}
.onChange(of: fruit, perform: { _ in
    type = .fruitTea
})

When I choose another kind of fruit tea that is already chosen, it works. But If I choose what is default value, my TypeOfTea won't change. I know why - because there was no change. But for my app clicking on Picker means choosing type. Can you please help? Thanks.

In case someone is interested in my all app:

My app on github

Marcel M.
  • 13
  • 4
  • Changing to: .onReceive([self.latte].publisher.first()) { _ in type = .teaLatte } for each picker will just crash the app – Marcel M. Nov 22 '22 at 22:12

2 Answers2

0

I don't know exactly if I understand your problem, but as you mentioned yourself there is no change. And your TypeOfTea remains a constant .fruitTea. But you could try something like that to actually trigger changes.

struct ContentView: View {
    @State private var type: TypeOfTea = .specialTeaPresso
    @State private var fruit: FruitTea = .passionFruit

    var body: some View {
        VStack {
            Picker("Fruit Tea", selection: $fruit) {
                ForEach(FruitTea.allCases, id: \.self) {
                    Text($0.rawValue).tag($0)
                }
            }

            Text(type.description)
        }
        .onChange(of: fruit, perform: { newFruit in
            type = newFruit.typeOfTea
        })

    }
}

struct MyPreviewProvider_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


enum FruitTea: String, CustomStringConvertible, CaseIterable, Codable {
    case peach = "Peach"
    case passionFruit = "Passion Fruit"
    case mango = "Mango"
    case greenApple = "Green Apple"
    var description: String { rawValue }

    var typeOfTea: TypeOfTea {
        switch self {
            case .peach:
                return .fruitTea
            case .passionFruit:
                return .teaLatte
            case .mango:
                return .mousseSeries
            case .greenApple:
                return .milkTea
        }
    }

}

enum TypeOfTea: String, CustomStringConvertible, CaseIterable, Codable {
    case specialTeaPresso = "Special Tea Presso"
    case teaLatte = "Tea Latte"
    case mousseSeries = "Mousse Series"
    case milkTea = "Milk Tea"
    case fruitTea = "Fruit Tea"
    var description: String { rawValue }
}

Meritum
  • 61
  • 1
  • Well I think my description of problem wasn't exact. I have 5 pickers total - each for specific type of tea (fruit, teaLatte, speciaTeaPressol, ...) each type of tea has its own kinds - so FuitTeaType has peach fruit tea, mango fruit tea, ... teaLatte has also several kinds - Matcha Tea Latte, Winter Mellon latte, ... I'm presenting pickers for. each type of tea (fruit, latte,...) but I don't know how to choose TypeOfTea while clicking on each Picker. Have a look at app on my github. – Marcel M. Nov 23 '22 at 13:12
0

I have found a solution based on: here

I have reduced those 5 pickers to 2. First to choose type of tea and second will show correct view using function that returns some View. Pickers had to be enclosed in AnyView().

Marcel M.
  • 13
  • 4