Невозможно передавать данные между представлениями, а также обновлять во втором представлении — SwiftUI

#ios #swift #swiftui #observedobject

#iOS #swift #swiftui #наблюдаемый объект

Вопрос:

Я пытаюсь передать данные между 2 представлениями, используя @Published и @ObservedObject следуя этой статье, но по какой-то причине я не могу передать данные, @Published просто сохраняется исходное состояние, в котором оно было задано, вместо изменения при нажатии кнопки.

Первое представление ProductList2 переходит к представлению вкладок, и я пытаюсь передать данные в одно из представлений вкладок. Любая помощь будет оценена.

Вот мое представление, в котором я создаю ObservableObject и @Published

 class selectedApplication: ObservableObject {
    @Published var selectedApplication = "All"
}

struct ProductList2: View {
    @ObservedObject var selectedOption = selectedApplication()
    var products: [ProductModel] = productData
    
    var body: some View {
        VStack {
            HStack {
                List{
                    ForEach(applicationsArray, id: .self) { item in
                        Button(action: {
                            self.selectedOption.selectedApplication = item
                        }) {
                            HStack(){
                                Image(item)
                                Text(item)
                            }
                        }
                    }
                }
            }
            List{
                let matchedItems = products.filter {
                    product in
                    let list = product.application
                    for item in list {
                        if item == selectedOption.selectedApplication {
                            return true
                        }
                    }
                    return false
                }
                ForEach(matchedItems) { item in
                    NavigationLink(destination: ProductTabView(product: item)) {
                        ProductListRow(product: item)
                    }
                }
            }
        }
    }
}
  

Это представление tabview, в котором я пытаюсь получить данные:

 struct ProductTab5View: View {
    var product: ProductModel
    @ObservedObject private var application = selectedApplication()
    
    var body: some View {
        VStack(alignment: .leading){
            Text(product.detailTabNames[3])
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(alignment: .center, spacing: 0){
                    ForEach(product.application, id: .self) { item in
                            Button(action: {
                                application.selectedApplication = item
                            }) {
                                VStack {
                                    Image(item)
                                    Text(item)
                                }
                            }
                    }
                }
            }            
            VStack(alignment: .center){
                Text(application.selectedApplication)
            }
        } 
    }
}
  

Редактировать:

Я обновил навигационную ссылку и @ObservedObject все еще не могу заставить ее работать:

Это обновленная навигационная ссылка ProductList2:

 ForEach(matchedItems) { item in
                        NavigationLink(destination: ProductTabView(product: item, application: selectedOption.selectedApplication)){
                            ProductListRow(product: item)
                        }
                    }
  

И это @ObservedObject в ProductTab5View, я также не могу заставить предварительный просмотр работать:

 @ObservedObject private var application: selectedApplication

struct ProductTab5View_Previews: PreviewProvider {
    static var previews: some View {
        ProductTab5View(product: productData[0], application: application)
    }
}
  

Ответ №1:

Вы используете два разных экземпляра selectedApplication :

 struct ProductList2: View {
    @ObservedObject var selectedOption = selectedApplication()
  
 struct ProductTab5View: View {
    ...
    @ObservedObject private var application = selectedApplication()
  

Вам необходимо использовать один и тот же экземпляр в обоих представлениях.

 struct ProductTab5View: View {
    ...
    @ObservedObject var application: selectedApplication // declare only
  
 // pass the already created instance to the child view
NavigationLink(destination: ProductTabView(product: item, application: selectedOption))
  

Комментарии:

1. Спасибо, я обновил ObservedObject , но я не могу, NavigationLink не работает. Я получаю эту ошибку Дополнительный аргумент «приложение» в вызове

2. @spoax Я имею в виду, что всякий раз, когда вы используете selectedApplication в любом дочернем представлении ( ProductTabView и ProductTab5View т.д.), Вам нужно передать приложение в это представление вместо создания нового selectedApplication .

3. Я понимаю, но когда я пытаюсь передать selectedOption via application в навигационной ссылке, я получаю сообщение об ошибке Дополнительный аргумент «приложение» в вызове . Это потому ObservedObject , что это частная переменная?

4. @spoax Да, вы можете либо предоставить свой собственный init, либо удалить private из ObservedObject var.

5. Извините, я действительно не могу заставить его работать! Я обновил, чтобы показать, что происходит не так.