how to populate picker from ViewModel object, setting to initial state of first element and handle actions on selection of picker item

我怕爱的太早我们不能终老 提交于 2020-03-25 19:00:13

问题


I have a view class showing list of items coming from ViewModel class, in picker. Initial state of this picker is first element from the array of objects of the viewModel class.

On selection of item from picker, I want to do different actions in that view - 1. send the object info to different screen on button click. 2. display information with respected to selected object from picker.

import SwiftUI
import Combine
struct SetConfiguration: View {


@ObservedObject var profileListVM : ProfilesListViewModel = ProfilesListViewModel()  
@State private var selectedConfiguration  = 0 ///show "Add" as initial state
var body: some View {
HStack {
        Text("Configuration:")

        Picker(selection: $selectedConfiguration.onChange(connectToConfiguration), label: EmptyView()) {
            ForEach(profileListVM.profiles, id: \.self) {
                          choice in
                Text(choice.name).tag(choice)
            }
        }

        Text (“Selcted item is: \(self. selectedconfiguration.name)”)

        Button(action: {

        }) {
            Text("Edit")
        }.sheet(isPresented: $showEditConfig) {
            EditConfigurationView()
                                         //  TODO pass  selectedConfiguration as profile object
        }

      }  

}

viewModel class:

class ProfilesListViewModel: ObservableObject { 
 @Published var profiles: [ProfileViewModel] = [ProfileViewModel]()   
static var addNewProfile = ProfileViewModel(name: "Add Configuration")
init() {
    fetchAllProfiles()
}
func fetchAllProfiles() {
     profiles.append(ProfilesListViewModel.addNewProfile) ///Add is first object
    self.profiles = CoreDataManager.shared.getConfigurations().map(ProfileViewModel.init) /// fetch all profile objects    
}

}


回答1:


Oh, ok. I'm in the context. But be careful, in future you'll be downvoted with such a quality of question. Here is the working example but read "P.S.", please, to avoid missunderstood in future:

// MARK: MOCKS FOR MODELS
struct ProfileViewModel: Hashable {
    let id = UUID()
    let name: String
}

class CoreDataManager {
    static let shared = CoreDataManager()

    func getConfigurations() -> [ProfileViewModel] {
        return [ProfileViewModel(name: "first"), ProfileViewModel(name: "second"),  ProfileViewModel(name: "third")]
    }
}

// MARK: changed class because it's not even working because of lack of code
class ProfilesListViewModel: ObservableObject {

    @Published var profiles: [ProfileViewModel] = [ProfileViewModel]()
    static var addNewProfile = ProfileViewModel(name: "Add Configuration")

    init() {
        fetchAllProfiles()
    }

    func fetchAllProfiles() {
        print("fetched")
        profiles.append(ProfilesListViewModel.addNewProfile) ///Add is first object
        self.profiles = CoreDataManager.shared.getConfigurations()
    }

}

// MARK: the solution
struct SetConfiguration: View {

    @ObservedObject var profileListVM: ProfilesListViewModel = ProfilesListViewModel()
    @State private var selectedConfiguration = 0 ///show "Add" as initial state
    @State private var choosedConfiguration = 0

    var body: some View {

        VStack {

            HStack {

                Picker(selection: $selectedConfiguration.onChange(selectNewConfig), label: Text("Configuration")) {
                    ForEach(0 ..< self.profileListVM.profiles.count) { choice in
                        Text(self.profileListVM.profiles[choice].name).tag(choice)
                    }
                }
            }

            Text("Selected item is: \(choosedConfiguration)")

        }

    }

    func selectNewConfig(_ newValue: Int) {
        print(newValue)
        withAnimation {
            choosedConfiguration = newValue
        }

    }

}

P.S.:

first: you should add all the working code and links, or simplify it to be clear what you want to achieve. Not every swift developer know about extension Binding, so they will just say: onChange will not ever work and they will be right;

second: format your code;

third: add some examples of your models or remove/simplify them.

the last one: I believe, you don't need choosedConfiguration, you can do some experiments with this.



来源:https://stackoverflow.com/questions/60681453/how-to-populate-picker-from-viewmodel-object-setting-to-initial-state-of-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!