как заполнить средство выбора из объекта ViewModel, установить исходное состояние первого элемента и выполнить действия при выборе элемента средства выбора - PullRequest
0 голосов
/ 14 марта 2020

У меня есть класс представления, показывающий список элементов, поступающих из класса 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 Ответ

1 голос

Я считаю это контекст для вашего вопроса. Вот рабочий пример:

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

    }

}

Советы

Чтобы избежать недопонимания в будущем:

  1. , вы должны добавить весь рабочий код и ссылки Или упростите это, чтобы было ясно, чего вы хотите достичь. Не каждый быстрый разработчик знает о extension Binding, поэтому они просто скажут: onChange никогда не будет работать, и они будут правы;

  2. отформатируйте ваш код;

  3. Добавьте несколько примеров ваших моделей или удалите / упростите их.

  4. Я полагаю, вам не нужно choosedConfiguration, вы можете провести некоторые эксперименты с этим.

...