@ Наблюдаемые изменения модели, не отраженные в представлении - PullRequest
0 голосов
/ 04 октября 2019

Ниже приведен пример реализации для тестирования функции @Observable в SwiftUI. Он содержит простое представление списка и подробное представление.

Мы можем добавлять объекты в список (и они отражаются в представлении). Мы можем перейти к подробному просмотру и редактировать имя, описание. Но эти изменения не отражаются на предыдущем экране (в списке).

Это не правильный путь, или я должен использовать только переменную @EnvirnomentObject, чтобы получить желаемый результат?

import SwiftUI

struct ContentView: View {
    @ObservedObject var model: ModelOne
    var body: some View {
        NavigationView{
            List(){
                ForEach(model.items,id: \.id){
                    item in
                    NavigationLink(destination: DetailView(item: item)){
                        VStack(alignment: .leading){
                            Text(item.name).lineLimit(1)
                            Text(item.description).lineLimit(1)
                        }.onAppear {
                            print("\(item.name)")
                        }
                    }
                }
            }.navigationBarTitle("List", displayMode: .inline)
                .navigationBarItems(trailing: AddItem(buttonAction: {
                    let newItem = Items()
                    newItem.name = "Empty"
                    newItem.description = "Empty"
                    self.model.items.append(newItem)
                }))
        }
    }
}

struct AddItem: View {
    var buttonAction: (()->Void)
    var body: some View{
        Button(action: {
            self.buttonAction()
        }){
            Text("Add")
        }
    }
}

class ModelOne: ObservableObject{
    @Published var items: [Items] = []
}

class Items: Identifiable{
    var id: UUID = UUID()
    var name: String = ""
    var description: String = ""
}

Детальный просмотр:

import SwiftUI

struct DetailView: View {
    @ObservedObject var item: Items
    var body: some View {
        VStack{
            TextField(item.name, text: $item.name)
            TextField(item.description, text: $item.description)
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 06 октября 2019

body в ContentView наблюдает model - он не наблюдает элементы в строках, поэтому обновление определенного Items не вызывает обновления body в ContentView,

Самый простой способ решить эту проблему - переместить строку в собственную struct, которая наблюдает за элементом. Таким образом, при изменении элемента представление в строке будет обновлено:

struct ContentView: View {
    @ObservedObject var model: ModelOne
    var body: some View {
        NavigationView{
            List(){
                ForEach(model.items,id: \.id){
                    item in
                    NavigationLink(destination: DetailView(item: item)){
                        Row(item:item)
                    }
                }
            }.navigationBarTitle("List", displayMode: .inline)
                .navigationBarItems(trailing: AddItem(buttonAction: {
                    let newItem = Items()
                    newItem.name = "Empty"
                    newItem.description = "Empty"
                    self.model.items.append(newItem)
                }))
        }
    }
}

struct Row: View {

    @ObservedObject var item: Items

    var body: some View {
        NavigationLink(destination: DetailView(item: item)){
            VStack(alignment: .leading){
                Text(item.name).lineLimit(1)
                Text(item.description).lineLimit(1)
            }.onAppear {
                print("\(self.item.name)")  
            }
        }
    }

}

0 голосов
/ 05 октября 2019

У меня не было времени протестировать это, но я думаю, что ваш тип «Массив» не меняется и поэтому не вызывает издателя. Кроме того, вы наблюдаете один элемент в подробном представлении, но публикуете изменения в «массиве», и я не верю, что это сработает.

Попробуйте передать наблюдаемую модель в подробный вид и дополнительный параметр для конкретного элемента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...