Picker with attached functions.

Is there a way to attached multiple functions (via action) per selected option in a Picker (Wheelview)?

I have this code so far:

struct Picker1Zon: View {
    
    //Variable
    @EnvironmentObject var name: SelectNames
    
    //Waarden
    @EnvironmentObject var vuur: VuurValues
    @EnvironmentObject var aarde: AardeValues
    @EnvironmentObject var lucht: LuchtValues
    @EnvironmentObject var water: WaterValues
    
    //PickerSelect
    @EnvironmentObject var picker: PickerSelectValues
    
    //Profiles
    @ObservedObject var profileRam = RamProfile()
    @ObservedObject var profileStier = StierProfile()
    @ObservedObject var profileTweelingen = TweelingenProfile()
    @ObservedObject var profileKreeft = KreeftProfile()
    @ObservedObject var profileLeeuw = LeeuwProfile()
    @ObservedObject var profileMaagd = MaagdProfile()
    @ObservedObject var profileWeegschaal = WeegschaalProfile()
    @ObservedObject var profileSchorpioen = SchorpioenProfile()
    @ObservedObject var profileBoogschutter = BoogschutterProfile()
    @ObservedObject var profileSteenbok = SteenbokProfile()
    @ObservedObject var profileWaterman = WatermanProfile()
    @ObservedObject var profileVissen = VissenProfile()
    
    var body: some View {
        
        VStack{
            Picker(selection: $name.Select1Variable , label: Text("")){
                Group {
                    Text("Selecteer...").tag("                ")
                    Text("\(profileRam.sterrenbeeldIcon)  Ram").tag("Ram")
                    Text("\(profileStier.sterrenbeeldIcon)  Stier").tag("Stier")
                    Text("\(profileTweelingen.sterrenbeeldIcon)  Tweelingen").tag("Tweelingen")
                    Text("\(profileKreeft.sterrenbeeldIcon)  Kreeft").tag("Kreeft")
                    Text("\(profileLeeuw.sterrenbeeldIcon)  Leeuw").tag("Leeuw")
                    Text("\(profileMaagd.sterrenbeeldIcon)  Maagd").tag("Maagd")
                }
                Group {
                    Text("\(profileWeegschaal.sterrenbeeldIcon)  Weegschaal").tag("Weegschaal")
                    Text("\(profileSchorpioen.sterrenbeeldIcon)  Schorpioen").tag("Schorpioen")
                    Text("\(profileBoogschutter.sterrenbeeldIcon)  Boogschutter").tag("Boogschutter")
                    Text("\(profileSteenbok.sterrenbeeldIcon)  Steenbok").tag("Steenbok")
                    Text("\(profileWaterman.sterrenbeeldIcon)  Waterman").tag("Waterman")
                    Text("\(profileVissen.sterrenbeeldIcon)  Vissen").tag("Vissen")
                }
            }
            .pickerStyle(WheelPickerStyle())
            .padding(.horizontal, 90.0)
            .background(content: {
                Rectangle()
                    .foregroundColor(.white)
                    .padding(.vertical, -15)
                    .cornerRadius(17)
                    .frame(width: 250, height: 200)
            })
            
        }
        .animation(.easeInOut(duration: 0.35).delay(0.25), value: picker.picker1)
        .scaleEffect(picker.picker1 ? 1 : 0)
        .opacity(picker.picker1 ? 1 : 0.2)
        .animation(.easeInOut(duration: 0.30), value: picker.picker1)

    }
    
}

.

In this code design I have only one observed variable that changes, but I would like to change multiple. Is there a way to do this?

Accepted Reply

I would use on Change modifier

Picker(selection: $name.Select1Variable , label: Text("")){
       // Group code
       // Group code
}
.onChange(of: name.Select1Variable) {[oldValue] newValue in // You can get the oldValue if needed
          switch newValue {
           case /* the appropriate value for RAM */:
                name.Select1Variable = "Ram "
                name.vuurZonValue = 18
                name.aardeZonValue = 0
                name.luchtZonValue = 0
                name.waterZonValue = 0
         }
}

Of course, you could put the switch in a func, for cleaner code…

Replies

> In this code design I have only one observed variable that changes, but I would like to change multiple Could you illustrate what you want to achieve ?

In this code:

  • which is the observed var that changes ?
  • it changes on Picker selection ?

Hi!

For example, if I select Text("\(profileRam.sterrenbeeldIcon) Ram").tag("Ram") on the wheel I want the following things to change:

name.Select1Variable = "Ram ", name.vuurZonValue = 18, name.aardeZonValue = 0, name.luchtZonValue = 0, name.waterZonValue = 0

Currently only the name.Select1Variable changes with the added .tag, but I would like to add the other 4 changes as well.

.

Another example, if I select Text("\(profileStier.sterrenbeeldIcon) Stier").tag("Stier") on the wheel, I would like the following this to change:

name.Select1Variable = "Stier ", name.vuurZonValue = 0, name.aardeZonValue = 18, name.luchtZonValue = 0, name.waterZonValue = 0

Same here, currently only the name.Select1Variable changes with the added .tag, but I would like to add the other 4 changes as well.

.

I've posted the observed data that are in a different Swift File below in an other reply so that you can see those as well.

The is the code in the observed data file.

import Foundation
import SwiftUI

class SelectNames: ObservableObject {
    
    @Published var Select1Variable = "                "
    @Published var Select2Variable = "                "
    @Published var Select3Variable = "                "
    @Published var Select4Variable = "                "
    @Published var Select5Variable = "                "
    @Published var Select6Variable = "                "
    @Published var Select7Variable = "                "
    @Published var Select8Variable = "                "
    @Published var Select9Variable = "                "
    @Published var Select10Variable = "                "
    @Published var Select11Variable = "                "
    @Published var Select12Variable = "                "
  

    func ResetAll() {
        Select1Variable = "                "
        Select2Variable = "                "
        Select3Variable = "                "
        Select4Variable = "                "
        Select5Variable = "                "
        Select6Variable = "                "
        Select7Variable = "                "
        Select8Variable = "                "
        Select9Variable = "                "
        Select10Variable = "                "
        Select11Variable = "                "
        Select12Variable = "                "
        
    }
    func ResetAll2() {
        Select1Variable = "Selecteer...    "
        Select2Variable = "Selecteer...    "
        Select3Variable = "Selecteer...    "
        Select4Variable = "Selecteer...    "
        Select5Variable = "Selecteer...    "
        Select6Variable = "Selecteer...    "
        Select7Variable = "Selecteer...    "
        Select8Variable = "Selecteer...    "
        Select9Variable = "Selecteer...    "
        Select10Variable = "Selecteer...    "
        Select11Variable = "Selecteer...    "
        Select12Variable = "Selecteer...    "
        
    }

    
    
    
    
    //VUUR——————————————
    @Published var vuurZonValue = 0
    @Published var vuurMaanValue = 0
    @Published var vuurAscedantValue = 0
    @Published var vuurMercuriusValue = 0
    @Published var vuurVenusValue = 0
    @Published var vuurMarsValue = 0
    @Published var vuurJupiterValue = 0
    @Published var vuurSaturnusValue = 0
    @Published var vuurMCValue = 0
    @Published var vuurUranusValue = 0
    @Published var vuurNeptunesValue = 0
    @Published var vuurPlutoValue = 0
    
    

    func sumValuesVuur() -> Int {
        return vuurZonValue + vuurMaanValue + vuurAscedantValue + vuurMercuriusValue + vuurVenusValue + vuurMarsValue + vuurJupiterValue + vuurSaturnusValue + vuurMCValue + vuurUranusValue + vuurNeptunesValue + vuurPlutoValue
    }
    
    

    func vuurResetAll() {
        vuurZonValue = 0
        vuurMaanValue = 0
        vuurAscedantValue = 0
        vuurMercuriusValue = 0
        vuurVenusValue = 0
        vuurMarsValue = 0
        vuurJupiterValue = 0
        vuurSaturnusValue = 0
        vuurMCValue = 0
        vuurUranusValue = 0
        vuurNeptunesValue = 0
        vuurPlutoValue = 0
    }

    
    
    
    
    //AARDE——————————————
    @Published var aardeZonValue = 0
    @Published var aardeMaanValue = 0
    @Published var aardeAscedantValue = 0
    @Published var aardeMercuriusValue = 0
    @Published var aardeVenusValue = 0
    @Published var aardeMarsValue = 0
    @Published var aardeJupiterValue = 0
    @Published var aardeSaturnusValue = 0
    @Published var aardeMCValue = 0
    @Published var aardeUranusValue = 0
    @Published var aardeNeptunesValue = 0
    @Published var aardePlutoValue = 0

    func sumValuesAarde() -> Int {
        return aardeZonValue + aardeMaanValue + aardeAscedantValue + aardeMercuriusValue + aardeVenusValue + aardeMarsValue + aardeJupiterValue + aardeSaturnusValue + aardeMCValue + aardeUranusValue + aardeNeptunesValue + aardePlutoValue
    }
    
    func aardeResetAll() {
        aardeZonValue = 0
        aardeMaanValue = 0
        aardeAscedantValue = 0
        aardeMercuriusValue = 0
        aardeVenusValue = 0
        aardeMarsValue = 0
        aardeJupiterValue = 0
        aardeSaturnusValue = 0
        aardeMCValue = 0
        aardeUranusValue = 0
        aardeNeptunesValue = 0
        aardePlutoValue = 0
    }
    
       
    
       
       
    //LUCHT——————————————
    @Published var luchtZonValue = 0
    @Published var luchtMaanValue = 0
    @Published var luchtAscedantValue = 0
    @Published var luchtMercuriusValue = 0
    @Published var luchtVenusValue = 0
    @Published var luchtMarsValue = 0
    @Published var luchtJupiterValue = 0
    @Published var luchtSaturnusValue = 0
    @Published var luchtMCValue = 0
    @Published var luchtUranusValue = 0
    @Published var luchtNeptunesValue = 0
    @Published var luchtPlutoValue = 0
    
    func sumValuesLucht() -> Int {
        return luchtZonValue + luchtMaanValue + luchtAscedantValue + luchtMercuriusValue + luchtVenusValue + luchtMarsValue + luchtJupiterValue + luchtSaturnusValue + luchtMCValue + luchtUranusValue + luchtNeptunesValue + luchtPlutoValue
    }

    func luchtResetAll() {
        luchtZonValue = 0
        luchtMaanValue = 0
        luchtAscedantValue = 0
        luchtMercuriusValue = 0
        luchtVenusValue = 0
        luchtMarsValue = 0
        luchtJupiterValue = 0
        luchtSaturnusValue = 0
        luchtMCValue = 0
        luchtUranusValue = 0
        luchtNeptunesValue = 0
        luchtPlutoValue = 0
    }
 
    
    
    
    
    //WATER——————————————
    @Published var waterZonValue = 0
    @Published var waterMaanValue = 0
    @Published var waterAscedantValue = 0
    @Published var waterMercuriusValue = 0
    @Published var waterVenusValue = 0
    @Published var waterMarsValue = 0
    @Published var waterJupiterValue = 0
    @Published var waterSaturnusValue = 0
    @Published var waterMCValue = 0
    @Published var waterUranusValue = 0
    @Published var waterNeptunesValue = 0
    @Published var waterPlutoValue = 0

    func sumValuesWater() -> Int {
        return waterZonValue + waterMaanValue + waterAscedantValue + waterMercuriusValue + waterVenusValue + waterMarsValue + waterJupiterValue + waterSaturnusValue + waterMCValue + waterUranusValue + waterNeptunesValue + waterPlutoValue
    }
    
    func waterResetAll() {
        waterZonValue = 0
        waterMaanValue = 0
        waterAscedantValue = 0
        waterMercuriusValue = 0
        waterVenusValue = 0
        waterMarsValue = 0
        waterJupiterValue = 0
        waterSaturnusValue = 0
        waterMCValue = 0
        waterUranusValue = 0
        waterNeptunesValue = 0
        waterPlutoValue = 0
    }   
}

I would use on Change modifier

Picker(selection: $name.Select1Variable , label: Text("")){
       // Group code
       // Group code
}
.onChange(of: name.Select1Variable) {[oldValue] newValue in // You can get the oldValue if needed
          switch newValue {
           case /* the appropriate value for RAM */:
                name.Select1Variable = "Ram "
                name.vuurZonValue = 18
                name.aardeZonValue = 0
                name.luchtZonValue = 0
                name.waterZonValue = 0
         }
}

Of course, you could put the switch in a func, for cleaner code…

Hi! I have implemented your suggestion, but I get an error about 'oldValue'. The error that I get is this: "Cannot find 'oldValue' in scope".

This is how I've implemented you suggestion in the code:

import SwiftUI
struct Picker1Zon: View {
    
    //Variable
    @EnvironmentObject var name: SelectNames
    
    //Waarden
    @EnvironmentObject var vuur: VuurValues
    @EnvironmentObject var aarde: AardeValues
    @EnvironmentObject var lucht: LuchtValues
    @EnvironmentObject var water: WaterValues
    
    //PickerSelect
    @EnvironmentObject var picker: PickerSelectValues
    
    //Profiles
    @ObservedObject var profileRam = RamProfile()
    @ObservedObject var profileStier = StierProfile()
    @ObservedObject var profileTweelingen = TweelingenProfile()
    @ObservedObject var profileKreeft = KreeftProfile()
    @ObservedObject var profileLeeuw = LeeuwProfile()
    @ObservedObject var profileMaagd = MaagdProfile()
    @ObservedObject var profileWeegschaal = WeegschaalProfile()
    @ObservedObject var profileSchorpioen = SchorpioenProfile()
    @ObservedObject var profileBoogschutter = BoogschutterProfile()
    @ObservedObject var profileSteenbok = SteenbokProfile()
    @ObservedObject var profileWaterman = WatermanProfile()
    @ObservedObject var profileVissen = VissenProfile()
    
    var body: some View {
        
        VStack{
            Picker(selection: $name.Select1Variable , label: Text("")){
                Group {
                    Text("Selecteer...")
                    Text("\(profileRam.sterrenbeeldIcon)  Ram")
                    Text("\(profileStier.sterrenbeeldIcon)  Stier")
                    Text("\(profileTweelingen.sterrenbeeldIcon)  Tweelingen")
                    Text("\(profileKreeft.sterrenbeeldIcon)  Kreeft")
                    Text("\(profileLeeuw.sterrenbeeldIcon)  Leeuw")
                    Text("\(profileMaagd.sterrenbeeldIcon)  Maagd")
                }
                Group {
                    Text("\(profileWeegschaal.sterrenbeeldIcon)  Weegschaal")
                    Text("\(profileSchorpioen.sterrenbeeldIcon)  Schorpioen")
                    Text("\(profileBoogschutter.sterrenbeeldIcon)  Boogschutter")
                    Text("\(profileSteenbok.sterrenbeeldIcon)  Steenbok")
                    Text("\(profileWaterman.sterrenbeeldIcon)  Waterman")
                    Text("\(profileVissen.sterrenbeeldIcon)  Vissen")
                }
            }
            .pickerStyle(WheelPickerStyle())
            .padding(.horizontal, 90.0)
            .background(content: {
                Rectangle()
                    .foregroundColor(.customWhite)
                    .padding(.vertical, -15)
                    .cornerRadius(17)
                    .frame(width: 250, height: 200)
            })
            .onChange(of: name.Select1Variable) {[oldValue] newValue in
                      switch newValue {
                       case "Selecteer...":
                            name.Select1Variable = "                "
                            name.vuurZonValue = 0
                            name.aardeZonValue = 0
                            name.luchtZonValue = 0
                            name.waterZonValue = 0
                      case "\(profileRam.sterrenbeeldIcon)  Ram":
                            name.Select1Variable = "Ram"
                            name.vuurZonValue = 18
                            name.aardeZonValue = 0
                            name.luchtZonValue = 0
                            name.waterZonValue = 0
                      case "\(profileStier.sterrenbeeldIcon)  Stier":
                            name.Select1Variable = "Stier"
                            name.vuurZonValue = 0
                            name.aardeZonValue = 18
                            name.luchtZonValue = 0
                            name.waterZonValue = 0
                     }
            }
        }
        .animation(.easeInOut(duration: 0.35).delay(0.25), value: picker.picker1)
        .scaleEffect(picker.picker1 ? 1 : 0)
        .opacity(picker.picker1 ? 1 : 0.2)
        .animation(.easeInOut(duration: 0.30), value: picker.picker1)

    }
    
}

In the image below you can see where I get the error message.

Is there a solution to this? Do I need to add or remove something?

oldValue was: name.Select1Variable)

You can

  • change to
.onChange (of: name.Select1Variable) {[name.Select1Variable)] newValue in
  • or remove [oldValue] as you don't use it

Here is an example from Picker documentation:

struct PlayerView: View {
    var episode: Episode
    @State private var playState: PlayState = .paused

    var body: some View {
        VStack {
            Text(episode.title)
            Text(episode.showTitle)
            PlayButton(playState: $playState)
        }
        .onChange(of: playState) { [playState] newState in
            model.playStateDidChange(from: playState, to: newState)
        }
    }
}

I've tried to remove, and as well change it to what you suggested but both times I get errors.

When I remove [oldValue], I get this error:

When I change it to what you suggested, I get this error:

So, you should remove the [oldValue]

For the switch, just add a default after the last case

default: break

Thank you so much for all the help! It works! 🤩

The final code I've used:


import SwiftUI
struct Picker1Zon: View {
    
    //Variable
    @EnvironmentObject var name: SelectNames
    
    //PickerSelect
    @EnvironmentObject var picker: PickerSelectValues
    
    //Profiles
    @ObservedObject var profileRam = RamProfile()
    @ObservedObject var profileStier = StierProfile()
    @ObservedObject var profileTweelingen = TweelingenProfile()
    @ObservedObject var profileKreeft = KreeftProfile()
    @ObservedObject var profileLeeuw = LeeuwProfile()
    @ObservedObject var profileMaagd = MaagdProfile()
    @ObservedObject var profileWeegschaal = WeegschaalProfile()
    @ObservedObject var profileSchorpioen = SchorpioenProfile()
    @ObservedObject var profileBoogschutter = BoogschutterProfile()
    @ObservedObject var profileSteenbok = SteenbokProfile()
    @ObservedObject var profileWaterman = WatermanProfile()
    @ObservedObject var profileVissen = VissenProfile()
    
    //ValueChanger
    var value = 18
    
    var body: some View {
        

            
        VStack{
            Picker(selection: $name.Select1Variable , label: Text("")){
                Group {
                    Text("Selecteer...").tag("Selecteer...")
                    Text("\(profileRam.sterrenbeeldIcon)  Ram").tag("Ram")
                    Text("\(profileStier.sterrenbeeldIcon)  Stier").tag("Stier")
                    Text("\(profileTweelingen.sterrenbeeldIcon)  Tweelingen").tag("Tweelingen")
                    Text("\(profileKreeft.sterrenbeeldIcon)  Kreeft").tag("Kreeft")
                    Text("\(profileLeeuw.sterrenbeeldIcon)  Leeuw").tag("Leeuw")
                    Text("\(profileMaagd.sterrenbeeldIcon)  Maagd").tag("Maagd")
                }
                Group {
                    Text("\(profileWeegschaal.sterrenbeeldIcon)  Weegschaal").tag("Weegschaal")
                    Text("\(profileSchorpioen.sterrenbeeldIcon)  Schorpioen").tag("Schorpioen")
                    Text("\(profileBoogschutter.sterrenbeeldIcon)  Boogschutter").tag("Boogschutter")
                    Text("\(profileSteenbok.sterrenbeeldIcon)  Steenbok").tag("Steenbok")
                    Text("\(profileWaterman.sterrenbeeldIcon)  Waterman").tag("Waterman")
                    Text("\(profileVissen.sterrenbeeldIcon)  Vissen").tag("Vissen")
                }
            }
            .onChange(of: name.Select1Variable) {newValue in
                switch newValue {
                case "Selecteer...":
                    name.Select1Variable = "          "
                    name.vuurZonValue = 0
                    name.aardeZonValue = 0
                    name.luchtZonValue = 0
                    name.waterZonValue = 0
                case "Ram":
                    name.Select1Variable = "Ram"
                    name.vuurZonValue = value
                    name.aardeZonValue = 0
                    name.luchtZonValue = 0
                    name.waterZonValue = 0
                case "Stier":
                    name.Select1Variable = "Stier"
                    name.vuurZonValue = 0
                    name.aardeZonValue = value
                    name.luchtZonValue = 0
                    name.waterZonValue = 0
                case "Tweelingen":
                    name.Select1Variable = "Tweelingen"
                    name.vuurZonValue = 0
                    name.aardeZonValue = 0
                    name.luchtZonValue = value
                    name.waterZonValue = 0
                case "Kreeft":
                    name.Select1Variable = "Kreeft"
                    name.vuurZonValue = 0
                    name.aardeZonValue = 0
                    name.luchtZonValue = 0
                    name.waterZonValue = value
                case "Leeuw":
                    name.Select1Variable = "Leeuw"
                    name.vuurZonValue = value
                    name.aardeZonValue = 0
                    name.luchtZonValue = 0
                    name.waterZonValue = 0
                case "Maagd":
                    name.Select1Variable = "Maagd"
                    name.vuurZonValue = 0
                    name.aardeZonValue = value
                    name.luchtZonValue = 0
                    name.waterZonValue = 0
                case "Weegschaal":
                    name.Select1Variable = "Weegschaal"
                    name.vuurZonValue = 0
                    name.aardeZonValue = 0
                    name.luchtZonValue = value
                    name.waterZonValue = 0
                case "Schorpioen":
                    name.Select1Variable = "Schorpioen"
                    name.vuurZonValue = 0
                    name.aardeZonValue = 0
                    name.luchtZonValue = 0
                    name.waterZonValue = value
                case "Boogschutter":
                    name.Select1Variable = "Boogschutter"
                    name.vuurZonValue = value
                    name.aardeZonValue = 0
                    name.luchtZonValue = 0
                    name.waterZonValue = 0
                case "Steenbok":
                    name.Select1Variable = "Steenbok"
                    name.vuurZonValue = 0
                    name.aardeZonValue = value
                    name.luchtZonValue = 0
                    name.waterZonValue = 0
                case "Waterman":
                    name.Select1Variable = "Waterman"
                    name.vuurZonValue = 0
                    name.aardeZonValue = 0
                    name.luchtZonValue = value
                    name.waterZonValue = 0
                case "Vissen":
                    name.Select1Variable = "Vissen"
                    name.vuurZonValue = 0
                    name.aardeZonValue = 0
                    name.luchtZonValue = 0
                    name.waterZonValue = value
                default:
                    break
                }
            }
            .pickerStyle(WheelPickerStyle())
            .padding(.horizontal, 90.0)
            .background(content: {
                Rectangle()
                    .foregroundColor(.customWhite)
                    .padding(.vertical, -15)
                    .cornerRadius(17)
                    .frame(width: 250, height: 200)
            })
            
        }
        .animation(.easeInOut(duration: 0.35).delay(0.25), value: picker.picker1)
        .scaleEffect(picker.picker1 ? 1 : 0)
        .opacity(picker.picker1 ? 1 : 0.2)
        .animation(.easeInOut(duration: 0.30), value: picker.picker1)
            

            
    }
    
}

struct Picker1Zon_Previews: PreviewProvider {
    static var previews: some View {
        Picker1Zon()
            .environmentObject(SelectNames())
            .environmentObject(PickerSelectValues())
    }
}
  • Thanks for the feedback and good continuation. The lesson is that in SwiftUI, modifiers are extremely important and useful.

Add a Comment