SwiftUI @Published объект не обновляет интерфейс для двойного массива структуры - PullRequest
0 голосов
/ 15 марта 2020

Я занимаюсь разработкой моего тестового приложения SwiftUI и у меня возникли проблемы с @Published и @ ObservedObject.

Вот мой код (к вашему сведению, я удалил несколько строк кода и добавил несколько фиктивных значений, чтобы вы могли легко их понять)

import SwiftUI

struct S0: Identifiable {
    var id = UUID()
    var arr: [S1] = []
}
struct S1: Identifiable {
    var i: Int
    var id = UUID()
}

class Model: ObservableObject {
    @Published var items: [S0] = [S0(arr: [S1(i: 100)])]
}

struct ContentView: View {
    @ObservedObject var testModel = Model()
    @State var flag = false
    var body: some View {
        VStack {
            List {
                ForEach (self.testModel.items){ item in
                    Text("\(item.arr.last?.i.description ?? "nil")")
                }
            }

            Button(action: {
                self.flag.toggle()
            }) {
                Text("Add")
            }.sheet(isPresented: $flag) {
                ModalView(flag: self.$flag).environmentObject(self.testModel)
            }
        }
    }
}

struct ModalView: View {
    @Binding var flag: Bool
    @EnvironmentObject var testModel: Model
    var body: some View {
        Button(action: {
            if let lastItem = self.testModel.items.last {
                var newItem = lastItem
                newItem.arr[0].i += 100
                self.testModel.items.append(newItem)
            }
            self.flag.toggle()
        }) {
            Text("add")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


Проблема в том, что когда я добавляю кнопку «Добавить», должны отображаться разные цифры (+100 к предыдущему номеру), но при этом отображаются одинаковые цифры (100)

Как видно из моего кода @Published использовал struct array, который также содержит struct array в качестве дочернего элемента. Если у меня нет дочернего массива struct array, он работает нормально.

Может кто-нибудь предложить мне хорошее решение для этого?

Спасибо.

1 Ответ

1 голос
/ 16 марта 2020

Я почти уверен, что ваша проблема в вашей бизнес-логике c и не связана с SwiftUI или каким-то неожиданным поведением Observable / Observed.

Давайте рассмотрим пример, который имитирует ваш код (вложенный массив в модели), который работает.

import SwiftUI

struct S0 {
    var arr: [S1] = []
}
struct S1 {
    var i: Int
}

class Model: ObservableObject {
    @Published var s0arr: [S0] = [S0(arr: [S1(i: 100)])]
}

struct ContentView: View {
    @ObservedObject var m = Model()
    @State var flag = false
    var body: some View {
        VStack {
            Text("\(m.s0arr.last?.arr.count ?? 0)")
            Text("\(m.s0arr.last?.arr.last?.i.description ?? "nil")").sheet(isPresented: $flag) {
                M(flag: self.$flag).environmentObject(self.m)
            }.onTapGesture {
                self.flag.toggle()
            }
        }
    }
}

struct M: View {
    @Binding var flag: Bool
    @EnvironmentObject var m: Model
    var body: some View {
        Button(action: {
            let c = self.m.s0arr.count
            if c > 0 {
                if let i = self.m.s0arr[c - 1].arr.last?.i {
                    self.m.s0arr[c - 1].arr.append(S1(i: i + 100))
                }
            }
            self.flag.toggle()
        }) {
            Text("add")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

и результирующее поведение

enter image description here

...