SwiftUI - 将数据传递到不同的视图
Posted
技术标签:
【中文标题】SwiftUI - 将数据传递到不同的视图【英文标题】:SwiftUI - pass data to different views 【发布时间】:2020-01-16 13:05:16 【问题描述】:我正在开发一个有 4 种不同视图的应用程序。主视图 (ContentView)、一个 AddView、一个 EditView 和一个单独的 DataView,其中包含我通过 ObservableObject 将所有数据传递给其他视图。
在主视图中,我有一个项目列表。在 AddView 中,我将项目添加到该列表和 ContentView。我希望能够使用导航链接编辑添加的项目。因此,我想从主视图转到 EditView,更改值,然后再次返回 ContentView,我会看到更改后的值。
您会使用 ObservableObject 来执行此操作,还是我需要 EnvironmentObject?因为目前 EditView 不起作用,我无法将数据从 ContentView 传递到 EditView, 上的所有文本字段EditView 为空,值不会被传递。它可以将数据从 AddView 传递到 ContentView,但不能从 ContentView 传递到 EditView。
谁能告诉我如何将数据链接到所有视图?
【问题讨论】:
使用@EnvironmentObject
。它允许所有添加了这个的视图共享包含共享数据的同一对象。如果您希望我发布示例答案,请告诉我。
如果您可以为我的项目发布一个带有主视图、添加视图和编辑视图的示例,那就太好了。提前致谢!
【参考方案1】:
您应该使用@EnvironmentObject
。它允许共享对象,这对于将数据共享给其他视图非常重要。
我在这个例子中使用了Shopping
对象。这个应用程序将像一个购物清单。整个项目在 GitHub here 上可用。
我真的希望这很有用,因为它花了很长时间。这只是一个一般示例,说明如何在View
s 之间有效地使用@EnvironmentObject
。
应用如下所示:
创建项目
(可以通过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:连同这个extension
,让可选的@State
s 工作(信用here,虽然这已经被简化了):
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
【讨论】:
非常感谢!这将帮助我完成我的应用程序:) @Distace 很高兴它有帮助! ? 我要感谢您付出额外的努力并为您的同行创建了一个特殊的项目。向您致敬,先生!以上是关于SwiftUI - 将数据传递到不同的视图的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据从子视图传递到父视图到 SwiftUI 中的另一个子视图?