如何从ViewModel对象填充选择器,如何设置第一个元素的初始状态以及如何处理选择器项目的选择 [英] how to populate picker from ViewModel object, setting to initial state of first element and handle actions on selection of picker item

查看:61
本文介绍了如何从ViewModel对象填充选择器,如何设置第一个元素的初始状态以及如何处理选择器项目的选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个视图类,在选择器中显示了来自ViewModel类的项目列表.该选择器的初始状态是viewModel类的对象数组中的第一个元素.

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.

从选择器中选择项目时,我想在该视图中执行不同的操作-1.单击按钮时,将对象信息发送到不同的屏幕.2.显示有关从选择器中选择的对象的信息.

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 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    
}

}

推荐答案

我相信

I believe this is the context for your question. Here is the working example:

// 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
        }

    }

}

提示

为避免将来产生误会:

Tips

To avoid misunderstandings in the future:

  1. 您应该添加所有有效的代码和链接,或者对其进行简化以明确您想要实现的目标.并非每个敏捷的开发人员都知道扩展绑定,所以他们只会说: onChange 永远行不通,而且是正确的;

  1. 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;

设置代码格式;

添加一些模型示例或删除/简化它们.

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

我相信,您不需要 choosedConfiguration ,您可以对此进行一些实验.

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

这篇关于如何从ViewModel对象填充选择器,如何设置第一个元素的初始状态以及如何处理选择器项目的选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆