如何从 ViewModel 对象填充选择器,设置为第一个元素的初始状态并处理选择选择器项的操作

Posted

技术标签:

【中文标题】如何从 ViewModel 对象填充选择器,设置为第一个元素的初始状态并处理选择选择器项的操作【英文标题】:how to populate picker from ViewModel object, setting to initial state of first element and handle actions on selection of picker item 【发布时间】:2020-03-14 09:43:18 【问题描述】:

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

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

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    

【问题讨论】:

你编译过这段代码吗?我几乎可以肯定答案是否定的...... 【参考方案1】:

我相信this is the context 是您的问题。这是工作示例:

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

    


提示

为避免日后误会:

    您应该添加所有工作代码和链接,或者将其简化以明确您想要实现的目标。不是每个 Swift 开发者都知道extension Binding,所以他们只会说:onChange 永远不会工作,他们是对的;

    格式化您的代码;

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

    我相信,你不需要choosedConfiguration,你可以用这个做一些实验。

【讨论】:

以上是关于如何从 ViewModel 对象填充选择器,设置为第一个元素的初始状态并处理选择选择器项的操作的主要内容,如果未能解决你的问题,请参考以下文章

从ViewModel设置条目的焦点

你是如何填充/验证你的 ViewModel 的?

如何从 DOM 节点转到 viewModel 对象?

如何从 NSStrings 数组中填充选择器视图?然后我将如何访问所选择项目的价值?

使用日期选择器填充日期下拉列表

选择步进器时滚动视图重叠