Dis*_*ace 4 xcode swift swiftui
我正在开发一个有 4 个不同视图的应用程序。主视图(ContentView)、一个AddView、一个EditView和一个分离的DataView,其中包含一个类,我通过ObservableObject将所有数据传递给其他视图。
在主视图中,我有一个项目列表。在AddView 中,我将项目添加到该列表和ContentView。我希望能够使用导航链接编辑添加的项目。所以从主视图我想转到EditView,更改值并再次返回ContentView,在那里我看到更改的值。
你会使用ObservableObject来做这件事还是我需要 EnvironmentObject?因为此刻EditView不工作,我无法将数据从ContentView传递到EditView,EditView 上的所有文本字段都是空的,值不会被传递。它可以将数据从AddView 传递到ContentView而不是从ContentView传递到EditView。
有人能告诉我如何将数据链接到所有视图吗?
Geo*_*e_E 12
你应该使用@EnvironmentObject
. 它允许共享一个对象,这对于将数据共享给其他视图非常重要。
我Shopping
在这个例子中使用了一个对象。这个应用程序就像一个购物清单。这整个项目可GitHub上的位置。
我真的希望这很有用,因为它花了很长时间。这只是如何在s之间有效使用的一般示例。@EnvironmentObject
View
该应用程序如下所示:
(可以通过GitHub下载,见上面的链接)
1:首先,在你的SceneDelegate.swift
,替换:
let contentView = ContentView()
Run Code Online (Sandbox Code Playgroud)
和:
let contentView = ContentView().environmentObject(Shopping())
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
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)
}))
}
}
}
Run Code Online (Sandbox Code Playgroud)
4:随着这个extension
让 optional @State
s 工作(信用在这里,虽然这已经简化了):
extension Optional where Wrapped == String {
var bound: String {
get {
return self ?? ""
}
set {
self = newValue
}
}
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4076 次 |
最近记录: |