Строки списка SwiftUI не обновляются после обновления привязки на другом экране - PullRequest
0 голосов
/ 30 января 2020

У меня есть простое приложение watchOS SwiftUI. Приложение имеет три экрана. Первый экран состоит из List элементов. Когда вы нажимаете этот элемент, он перенаправляется на другой экран, а когда вы нажимаете там кнопку, он открывает .sheet View, который позволяет редактировать элемент в списке.

Первый вид выглядит следующим образом:


class Object: NSObject {

    var title: String

    init(title: String) {
        self.title = title
    }

}

struct Row: View {

    @Binding var object: Object

    var body: some View {
        Text(self.object.title)
    }

}

struct ContentView: View {

    @State private var objects = [Object]()

    var body: some View {
        NavigationView {
            List {
                ForEach(objects.indices, id: \.self) { idx in
                    NavigationLink(destination: SecondView(object: self.$objects[idx])) {
                        Row(object: self.$objects[idx])
                    }
                }
            }
        }
        .onAppear {
            self.objects = [
                Object(title: "Test 1"),
                Object(title: "Test 2")
            ]
        }
    }

}

Это второй и третий виды:

struct SecondView: View {

    @Binding var object: Object
    @State private var showPicker: Bool = false

    var body: some View {
        VStack {
            Text(object.title)
            Button(action: {
                self.showPicker.toggle()
            }) {
                Text("Press Here")
            }
        }
        .sheet(isPresented: $showPicker) {
            ThirdView(object: self.$object)
        }
    }

}

struct ThirdView: View {

    @Binding var object: Object

    var body: some View {
        VStack {
            Text(object.title)
            Button(action: {
                self.update()
            }, label: {
                Text("Tap here")
            })
        }
    }

    func update() {
        let newObj = self.object
        newObj.title = "Hello, World!"
        self.object = newObj
    }

}

Я ожидаю, что всякий раз, когда я нажимаю кнопку в третьем представлении, Binding (и, следовательно, State) get обновлено с "Hello, World". Однако это не так, хотя и не сразу.

В настоящее время я вижу, что когда я нажимаю кнопку в третьем представлении, Text в этом представлении не обновляется. Когда я отклоняю третий вид и go возвращаюсь ко второму виду, я вижу «Привет, мир». Но когда я go вернусь к списку, строка все еще будет иметь старое значение.

Еще одна вещь, которую я заметил, это то, что, когда я заполняю массив объектов напрямую, вот так:

@State private var objects = [Object(title: "Test 1"), Object(title: "Test 2")]

и удалите заполнение массива в .onAppear, это работает полностью так, как я ожидал (все сразу обновляется до «Hello, World».

Кто-нибудь знает, кто я? » я делаю что-то не так, или я мог ошибиться?

Спасибо!

1 Ответ

0 голосов
/ 30 января 2020

Сложные объекты должны быть классами, соответствующими @ObservableObject. Наблюдаемые ивары должны быть опубликованы.

class Object: ObservableObject {
  @Published var title: String
  [...]
}

Наблюдающие представления будут использовать их как @ObservedObject

struct Row: View {
  @ObservedObject var object: Object
  [...]
}

Возможно, вам придется создать объектную оболочку для ваших списков

class ObjectList: ObservableObject {
  @Published var objects: [Object]
  [...]
}
...