skip to Main Content

I am trying to run a function after a user has selected a picker option.

The idea is that the user can set a default station, so I need to be able to send the selected value to a function so I can save it inside the core data module. How can I achieve this?

import SwiftUI

struct SettingsView: View {
    var frameworks = ["DRN1", "DRN1 Hits", "DRN1 United", "DRN1 Life"]
    @State private var selectedFrameworkIndex = 0
    
    func doSomethingWith(value: String) {
        print(value)
    }
    
    var body: some View {
        NavigationView {
            Form {
                Section {
                    Picker(selection: $selectedFrameworkIndex, label: Text("Favorite Station")) {
                        ForEach(0 ..< frameworks.count) {
                            Text(self.frameworks[$0])
                        }
                    }.onReceive([self.frameworks].publisher.first()) { value in
                        self.doSomethingWith(value: value)
                    }
                }
            }
            .navigationBarTitle("Settings")
        }
    }
}

3

Answers


  1. Instead of using onRecive try using onChange.

    Your code:

    .onReceive([self.frameworks].publisher.first()) { value in
        self.doSomethingWith(value: value)
    }
    

    Correction:

    .onChange(of: $selectedFrameworkIndex, perform: { value in
            self.doSomethingWith(value: value)
        })
    

    this will trigger every time $selectedFrameworkIndex is changed.

    Login or Signup to reply.
  2. I would use a simple .onChange(of:) call on the picker. It will pick up on the change of the @State var and allow you to act on it. Use it like this:

    import SwiftUI
    
    struct SettingsView: View {
       var frameworks = ["DRN1", "DRN1 Hits", "DRN1 United", "DRN1 Life"]
       @State private var selectedFrameworkIndex = 0
    
        
        func doSomethingWith(value: String) {
                print(value)
          }
        
       var body: some View {
        NavigationView {
                Form {
                    Section {
                        Picker(selection: $selectedFrameworkIndex, label: Text("Favorite Station")) {
                            ForEach(0 ..< frameworks.count) {
                                Text(self.frameworks[$0])
                            }
                        }
                         // Put your function call in here:
                         .onChange(of: selectedFrameworkIndex) { value in
                            print(value)
                        }
    
                        }
                    }
                }
                .navigationBarTitle("Settings")
            }
       }
    
    
    }
    
    Login or Signup to reply.
  3. yours:

    import SwiftUI
    
    struct SettingsView: View {
       var frameworks = ["DRN1", "DRN1 Hits", "DRN1 United", "DRN1 Life"]
       @State private var selectedFrameworkIndex = 0
       
       func doSomethingWith(value: String) {
           print(value)
       }
        
       var body: some View {
        NavigationView {
                Form {
                    Section {
                        Picker(selection: $selectedFrameworkIndex, label: Text("Favorite Station")) {
                            ForEach(0 ..< frameworks.count) {
                                Text(self.frameworks[$0])
                            }
                        }.onReceive([self.frameworks].publisher.first()) { value in
                            self.doSomethingWith(value: value)
                        }
                    }
                }
                .navigationBarTitle("Settings")
            }
       }
    
    
    }
    

    add a variable that checks to see if selectedFrameworkIndex has changed.
    change:

    import SwiftUI
    
    struct SettingsView: View {
        var frameworks = ["DRN1", "DRN1 Hits", "DRN1 United", "DRN1 Life"]
        @State private var selectedFrameworkIndex = 0
        @State private var savedFrameworkIndex = 0
        
       func handler<Value: Any>(val: Value) -> Value {
           if selectedFrameworkIndex != savedFrameworkIndex {
               self.doSomethingWith(value: self.frameworks[selectedFrameworkIndex])
           }
           return val
       }
    
        func doSomethingWith(value: String) {
            print(value)
        }
        var body: some View {
            NavigationView {
                Form {
                    Section {
                        Picker(selection: handler(val: $selectedFrameworkIndex), label: Text("Favorite Station")) {
                            ForEach(0 ..< frameworks.count) {
                                Text(self.frameworks[$0])
                            }
                        }
                    }
                }
                .navigationBarTitle("Settings")
            }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search