你应该使用 @EnvironmentObject
。它允许对象被共享,这对于将数据共享到其他视图非常重要。
在这个例子中,我正在使用一个 Shopping
对象。这个应用程序将像购物清单一样运作。整个项目可以在 GitHub 上找到 这里。
希望这很有用,因为花了相当长的时间。这只是一个关于如何在视图之间有效地使用 @EnvironmentObject
的通用示例。
应用程序看起来像这样:
![应用程序外观](https://istack.dev59.com/W5MT1.webp)
创建项目
(可以通过GitHub下载,参见上面的链接)
1: 首先,在您的 SceneDelegate.swift
中,将以下代码替换为:
let contentView = ContentView()
用:
let contentView = ContentView().environmentObject(Shopping())
2: 现在Xcode会抱怨Shopping
还没有被创建,因此我们接下来会修复它:
class Shopping: ObservableObject {
@Published var list = [
ShoppingItem("Bread", quantity: 1),
ShoppingItem("Milk", quantity: 2),
ShoppingItem("Eggs", quantity: 12)
]
func addItem(_ item: ShoppingItem) {
list.append(item)
}
}
class ShoppingItem: Identifiable {
var name: String
var quantity: Int
init(_ name: String, quantity: Int) {
self.name = name
self.quantity = quantity
}
}
3: 接下来,我们需要主要内容ContentView
:
struct ContentView: View {
@EnvironmentObject private var shopping: Shopping
@State private var newItem: String?
var body: some View {
NavigationView {
List {
ForEach(shopping.list) { item in
NavigationLink.init(destination: EditView(currentItem: item)) {
HStack {
Text(item.name)
Spacer()
Text(String(item.quantity))
Spacer().frame(width: 10)
}
}
}
if newItem != nil {
TextField("New Item", text: $newItem.bound, onCommit: {
if !self.newItem!.isEmpty {
self.shopping.addItem(ShoppingItem(self.newItem!, quantity: 1))
}
self.newItem = nil
})
}
}
.navigationBarTitle("Shopping List")
.navigationBarItems(trailing: Button(action: {
self.newItem = ""
}, label: {
Image(systemName: "plus.circle.fill")
.resizable()
.frame(width: 25, height: 25)
}))
}
}
}
4:除此之外,还有这个扩展
可以让可选的@State
工作(参考这里,尽管这已经被简化了):
extension Optional where Wrapped == String {
var bound: String {
get {
return self ?? ""
}
set {
self = newValue
}
}
}
第5步:最后是EditView
,允许您编辑购物清单中的项目名称:
struct EditView: View {
let currentItem: ShoppingItem
@EnvironmentObject private var shopping: Shopping
@State private var name = ""
var body: some View {
TextField("Item", text: $name, onCommit: saveName)
.padding()
.background(Color.gray)
.onAppear(perform: setName)
}
private func saveName() {
shopping.objectWillChange.send()
currentItem.name = name
}
private func setName() {
name = currentItem.name
}
}
@EnvironmentObject
。它允许所有添加了此对象的视图共享包含共享数据的同一对象。如果您想让我为您提供示例答案,请告诉我。 - George