如何从ViewModel对象填充选择器,如何设置第一个元素的初始状态以及如何处理选择器项目的选择 [英] how to populate picker from ViewModel object, setting to initial state of first element and handle actions on selection of picker item
问题描述
我有一个视图类,在选择器中显示了来自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:
-
您应该添加所有有效的代码和链接,或者对其进行简化以明确您想要实现的目标.并非每个敏捷的开发人员都知道
扩展绑定
,所以他们只会说:onChange
永远行不通,而且是正确的;
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屋!