我有三个视图。我的问题是,第一个(2的父视图)没有改变,当第三个(视图2的孩子)已经更新了数组中的属性。让我们使用一些代码,以便更容易理解:
public struct Item {
public let id: String
public var name: String?
public var inStock: Bool
import SwiftUI
@main
struct ThisIsMessedUpApp: App {
var body: some Scene {
WindowGroup {
ItemsMainView()
}
}
}
import Foundation
import SwiftUI
struct ItemsMainView: View {
@State var items = [Item]()
var body: some View {
VStack {
Text("Item count is (items.count)")
Divider()
VStack {
Text("ItemsMainView has:")
HStack {
ForEach(self.items, id: .id) { item in
Text(item.name ?? "nothing found")
Spacer()
Text(item.inStock.description)
}
}
}
ItemsView(items: $items)
}
}
}
struct ItemsView: View {
@Binding var items: [Item]
var body: some View {
Button("Add new item (call made from ItemsView", action: {
self.items.append(Item(id: UUID().uuidString,
name: "Test #1",
inStock: false))
})
VStack {
ForEach($items, id: .id) { $item in
ItemView(item: $item)
}
}
}
}
struct ItemView: View {
@Binding var item: Item
@State var draftItemName: String = ""
var body: some View {
Text("ItemView has")
HStack {
TextField("TextField", text: $draftItemName)
.onSubmit {
item.name = draftItemName
}
Spacer()
Text(item.inStock.description)
}
.onAppear {
draftItemName = item.name ?? ""
}
}
}
一些Text
是用于调试目的的。如果您运行这段代码并将第二个TextField
的值更改为"Test #2",您将看到最终的UI状态不一致:ItemsMainView
具有"Test #1",而ItemView
具有"Test #2">
在Xcode 14.2中,为ios或macos创建一个新项目。复制并粘贴以下代码,替换原ContentView
.
告诉我们,如果这个代码,测试在真正的ios 16.3设备(不是预览版),macCatalyst和MacOS 13.2仅为您工作。
struct ContentView: View {
var body: some View {
ItemsMainView()
}
}
public struct Item {
public let id: String
public var name: String?
public var inStock: Bool
}
struct ItemsMainView: View {
@State var items = [Item]()
var body: some View {
VStack {
Text("Item count is (items.count)")
Divider()
VStack {
Text("ItemsMainView has:")
ForEach(items, id: .id) { item in
HStack {
Text(item.name ?? "nothing found").foregroundColor(.red)
Spacer()
Text(item.inStock.description).foregroundColor(.red)
}
}
}
ItemsView(items: $items)
}
}
}
struct ItemsView: View {
@Binding var items: [Item]
var body: some View {
Button("Add new item (call made from ItemsView", action: {
self.items.append(Item(id: UUID().uuidString, name: "Test #1", inStock: false))
}).buttonStyle(.bordered)
VStack {
ForEach($items, id: .id) { $item in
ItemView(item: $item)
}
}
}
}
struct ItemView: View {
@Binding var item: Item
@State var draftItemName: String = ""
var body: some View {
Text("ItemView has")
HStack {
TextField("TextField", text: $draftItemName)
.onSubmit {
item.name = draftItemName
}
Spacer()
Text(item.inStock.description)
}
.onAppear {
draftItemName = item.name ?? ""
}
}
}