SwiftUI @Published object 不会为双结构数组更新 UI
SwiftUI @Published object doesn't update UI for double struct array
我正在开发我的 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 使用了结构数组,它还包含结构数组作为 child。
如果我没有结构数组 child,它工作正常。
任何人都可以为此建议我好的解决方案吗?
谢谢。
我几乎可以肯定,您的问题出在您的业务逻辑上,与 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()
}
}
和由此产生的行为
我正在开发我的 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 使用了结构数组,它还包含结构数组作为 child。 如果我没有结构数组 child,它工作正常。
任何人都可以为此建议我好的解决方案吗?
谢谢。
我几乎可以肯定,您的问题出在您的业务逻辑上,与 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()
}
}
和由此产生的行为