[英]How do I pass data from one SwiftUI view file to another?
The basic gist is I'm building a meal planner app.基本要点是我正在构建一个膳食计划应用程序。 I'm new to Swift and SwiftUI and this is my first project so I'm probably making a noob mistake lol Basically I want to pass the current index, which is a data object for a day and it's meals, to the DailyMealPlan view when I tap on the corresponding card.
我是 Swift 和 SwiftUI 的新手,这是我的第一个项目,所以我可能犯了一个菜鸟错误lol 基本上我想将当前索引传递给 DailyMealPlan 视图,该索引是一天的数据对象和膳食我点击相应的卡片。 I don't get an error when I pass the currentDay variable to the view, but inside the second view file I'm not sure how I handle that data.
将 currentDay 变量传递给视图时,我没有收到错误消息,但在第二个视图文件中,我不确定如何处理该数据。 I keep getting an error that "CurrentMealPlan is not in scope".
我不断收到“CurrentMealPlan 不在范围内”的错误消息。 I understand how scope works and I suspect I'm just missing something when it comes to passing the data into the second view.
我了解范围是如何工作的,我怀疑在将数据传递到第二个视图时我只是遗漏了一些东西。
ForEach code ForEach 代码
ForEach(CurrentMealPlan.indices) { index in
let currentDay = CurrentMealPlan[index]
NavigationLink(
destination: DailyMealPlan(DailyMealPlan: currentDay))
{
MealPlanCard(
Day: "\(CurrentMealPlan[index].DayTitle)",
Breakfast: "\(CurrentMealPlan[index].Breakfast)",
Lunch: "\(CurrentMealPlan[index].Lunch)",
Dinner: "\(CurrentMealPlan[index].Dinner)"
)
}
}
DailyMealPlan view DailyMealPlan 视图
struct DailyMealPlan: View {
var DailyMealPlan: Day = CurrentMealPlan[index]
var body: some View {
ZStack {
ScrollView {
VStack {
SingleMealCard(Meal: "Breakfast", CalCount: 500, MealInfo: "Meal info here")
SingleMealCard(Meal: "Lunch", CalCount: 500, MealInfo: "Meal info here")
SingleMealCard(Meal: "Dinner", CalCount: 500, MealInfo: "Meal info here")
}
}
}
}
}
CurrentMealPlan model当前膳食计划模型
struct Day: Hashable {
var id: Int
var Date: String
var DayTitle: String
var Breakfast: String
var Lunch: String
var Dinner: String
init(id:Int=0,Date:String="",DayTitle:String="",Breakfast:String="",Lunch:String="",Dinner:String="") {
self.id = id
self.Date = Date
self.DayTitle = DayTitle
self.Breakfast = Breakfast
self.Lunch = Lunch
self.Dinner = Dinner
}
}
let CurrentMealPlan: [Day] = [
Day(
id: 0,
DayTitle: "Sunday",
Breakfast:"Oatmeal",
Lunch: "Sandwich",
Dinner: "Cheeseburger with Fries"
)
]
Let's walk through your code.让我们来看看你的代码。 First, you declared the
CurrentMealPlan
array inside the parent view.首先,您在父视图中声明了
CurrentMealPlan
数组。 It probably looks something like this:它可能看起来像这样:
@State var CurrentMealPlan = [Day]()
Note: As jnpdx commented , you should lowercase property names like var currentMealPlan
and var dailyMealPlan
.注意:正如jnpdx 所评论的,您应该小写属性名称,例如
var currentMealPlan
和var dailyMealPlan
。 Also, you should not have the same name for the DailyMealPlan
view and the DailyMealPlan
property... it's extremely confusing.此外,
DailyMealPlan
视图和DailyMealPlan
属性不应具有相同的名称......这非常令人困惑。
Your code is correct.你的代码是正确的。 Then, you loop over
CurrentMealPlan
, and want to pass each element over to the DailyMealPlan
view:然后,您循环遍历
CurrentMealPlan
,并希望将每个元素传递给DailyMealPlan
视图:
DailyMealPlan(DailyMealPlan: currentDay))
That's also completely fine.这也完全没问题。 So where does the
CurrentMealPlan is not in scope
error come from?那么
CurrentMealPlan is not in scope
错误从何而来? It's this line:这是这一行:
var DailyMealPlan: Day = CurrentMealPlan[index] /// NO!
Remember, you declared CurrentMealPlan
inside the parent view, not the DailyMealPlan
view.请记住,您在父视图中声明了
CurrentMealPlan
,而不是DailyMealPlan
视图。 That means the DailyMealPlan
view can't access CurrentMealPlan
.这意味着
DailyMealPlan
视图无法访问CurrentMealPlan
。
However, the DailyMealPlan
view does not need to access CurrentMealPlan
.然而,
DailyMealPlan
视图不需要访问CurrentMealPlan
。 Back in the parent view, you're already looping through CurrentMealPlan
and passing in each currentDay
over to the DailyMealPlan
view.回到父视图,您已经在遍历
CurrentMealPlan
并将每个currentDay
传递到DailyMealPlan
视图。
So, all you need to do is define the type of the DailyMealPlan
property:因此,您需要做的就是定义
DailyMealPlan
属性的类型:
struct DailyMealPlan: View {
var DailyMealPlan: Day /// here!
...
}
This lets the compiler know that var DailyMealPlan
takes in a Day
.这让编译器知道
var DailyMealPlan
接受了Day
。
I suggest using a MVVM approach, each screen view should have it's own view model (which should be a class extending a base view model or protocol) which you pass when you create the view.我建议使用 MVVM 方法,每个屏幕视图都应该有它自己的视图模型(它应该是一个扩展基本视图模型或协议的类),您在创建视图时传递它。
In your case you should have:在你的情况下,你应该有:
protocol BaseViewModel {
}
class DailyMealPlanViewModel: BaseViewModel {
@Published var day: Day
}
in the above I also added day as @Published so any changes on that will refresh the view, if the day never changes you can remove @Published.在上面我还添加了@Published 的日期,因此任何更改都会刷新视图,如果这一天永远不会改变,您可以删除@Published。
in your view:在您看来:
struct DailyMealPlan: View {
@StateObject var viewModel: DailyMealPlanViewModel
...
...
And when navigating:导航时:
NavigationLink(
destination: DailyMealPlan(viewModel: DailyMealPlanViewModel(day: currentDay))
...
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.