如何在 SwiftUI 中将数据从视图传递到另一个视图?
Posted
技术标签:
【中文标题】如何在 SwiftUI 中将数据从视图传递到另一个视图?【英文标题】:How to pass data from a view to another view in SwiftUI? 【发布时间】:2021-12-13 10:09:48 【问题描述】:我正在处理一个大问题,我尝试了很多方法来解决这个问题,但确实没有找到合适的答案。
基本上,我有一个食物菜单列表,当我点击它们时,我想显示它们的内容,如能量、蛋白质、脂肪、碳水化合物等,但显示的只是一些 ID。我的后端有一件棘手的事情。
我会把代码放在下面,我会逐步解释:
这里是食物菜单:Food menus photo
List
Section(header: Text(Texts.meniuriViewText1))
ForEach(syncViewModel.menu.filter($0.type == 1359)) men in
HStack
NavigationLink(destination: ItemMenuView(meniu: men))
Image("healthyMeal")
.resizable()
.scaledToFit()
.frame(width: 100, height: 100)
.padding()
VStack(alignment: .leading, spacing: 10)
Text(men.name)
.font(.system(size: 16))
.foregroundColor(.black)
.fontWeight(.semibold)
HStack
Text("\(men.price) lei")
.fontWeight(.bold)
Text("\(men.ingredients[0].grams, specifier: "%.0f")g")
.font(.system(size: 16))
.fontWeight(.medium)
.foregroundColor(.gray)
Spacer()
Image(systemName: "plus")
.font(.title)
.foregroundColor(Color.onboardingColor)
.padding(20)
.onTapGesture
coreDataViewModel.addTask(name: men.name, grams: men.ingredients[0].grams, price: Int(men.price))
这是关于食物菜单的详细信息:Details photo
var meniu : Meniuri?
var body: some View
VStack
HStack
Text("Ingrediente")
.foregroundColor(.gray)
.padding(30)
Spacer()
ForEach(meniu!.ingredients) men in
HStack(spacing: 15)
Image("aubergine")
.padding(.leading, 30)
Text("\(men.ingredient)")
.foregroundColor(.colorGrayDark)
Spacer()
Text("\(men.grams, specifier: "%.0f")g")
.foregroundColor(.colorGrayDark)
.padding(.trailing, 30)
.padding(.bottom, 15)
这是我的菜单模型“Meniuri”:
struct Meniuri: Codable, Identifiable
let id: Int
let meta: ExtrasOptionMeta
let name: String
let ingredients: [Ingredients]
let type, price: Int
struct Ingredients: Codable, Identifiable
var id: Int ingredient
let ingredient: Int
let grams: Double
现在解释一下,成分模型中的“成分”属性在我的后端与此成分模型“项目链接”,因此成分中的成分属性基本上是成分模型中的 id。如何在“食物菜单的详细信息”中访问成分模型中的成分?
struct Ingredient: Model, Identifiable
static var itemName: String = "ingredient"
var id: Int
var meta: Meta
var name: String
var energy: Double
var protein, fats, carbohydrates, fiber: Double?
var saturatedFats, sugar, monosaturatedFats, polysaturatedFats: Double?
var cholesterol, calcium: Int?
var iron, magnesium: Double?
这就是我从互联网上检索数据的方式:
func fetchMenus()
_spaceOne.fetch(path: "/api/items", parameters: ["q" : "at'test' select item from 'menu'"]) result in
switch result
case .failed(let error):
print(error)
break
case .success(_, let data, _):
do
let meniu = try JSONDecoder().decode([Meniuri].self, from: data)
self.menu = meniu
catch
print(error)
break
func fetchIngredients ()
_spaceOne.fetch(Ingredient.self).all result in
switch result
case .failed(let error):
print(error)
break
case .success(let ingred):
self._ingredient = ingred
【问题讨论】:
我认为所有 swiftui 代码都与问题无关,这是关于您的数据源以及如何构建模型数据的问题。我不明白您实际上是如何获取成分的,但一种解决方案可能是将所有成分加载到缓存(字典)中,并使用 id 属性作为键从那里检索它们。另一种选择是不使用从后端获得的模型,而是将其映射到另一个模型中,在其中将Ingredients
对象替换为 Ingredient
对象,并可能进行一些其他更改以使模型对你更有用。
我在之前的评论中说过这都是关于模型层的,但您也可以考虑在模型和视图之间使用一些视图模型或控制器类,具体取决于您采用的路径。
你好@JoakimDanielson。首先,感谢您的回答。像这篇文章中用于获取成分和菜单的所有网络功能都在视图模型中。第二:我如何映射到另一个模型来用成分替换成分?
这对我来说很难回答,因为不清楚您是如何获取数据的
请澄清您的具体问题或提供更多详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。
【参考方案1】:
这是一个简单的例子:
struct ContentView: View
var body: some View
NavigationView
NavigationLink(destination: FeatureView1(title: "FeatureView1"))
Text("Go to FeatureView1")
struct FeatureView1 : View
var title: String
var body: some View
Text(title)
NavigationLink(destination: FeatureView2(title: "FeatureView2"))
Text("Go to FeatureView2")
struct FeatureView2 : View
var title: String
var body: some View
Text(title)
根据你的用例,还有很多其他的方法可以在视图之间共享数据,我让你稍后看到@EnvironmentObject、@Binding 等
【讨论】:
以上是关于如何在 SwiftUI 中将数据从视图传递到另一个视图?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Segue 在 Swift 中将带有数据的对象从一个视图传递到另一个视图
如何在没有 segue 的情况下在 Swift 3 中将数据从 VC 传递到另一个?