如何将数据从一个 SwiftUI 视图文件传递到另一个?
How do I pass data from one SwiftUI view file to another?
基本要点是我正在构建一个膳食计划应用程序。我是 Swift 和 SwiftUI 的新手,这是我的第一个项目,所以我可能犯了一个菜鸟错误大声笑基本上我想传递当前索引,这是一个数据当我点击相应的卡片时,一天的对象和它的膳食,到 DailyMealPlan 视图。当我将 currentDay 变量传递给视图时,我没有收到错误消息,但在第二个视图文件中,我不确定如何处理该数据。我不断收到“CurrentMealPlan 不在范围内”的错误消息。我了解范围的工作原理,我怀疑在将数据传递到第二个视图时我只是遗漏了一些东西。
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 视图
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")
}
}
}
}
}
当前膳食计划模型
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"
)
]
让我们浏览一下您的代码。首先,您在父视图中声明了 CurrentMealPlan
数组。它可能看起来像这样:
@State var CurrentMealPlan = [Day]()
注意:作为 ,您应该小写 属性 名称,例如 var currentMealPlan
和 var dailyMealPlan
。此外,不应该 DailyMealPlan
视图和 DailyMealPlan
属性 具有相同的名称...这非常令人困惑。
您的代码是正确的。然后,您遍历 CurrentMealPlan
,并希望将每个元素传递给 DailyMealPlan
视图:
DailyMealPlan(DailyMealPlan: currentDay))
那也完全没问题。那么 CurrentMealPlan is not in scope
错误从何而来?就是这一行:
var DailyMealPlan: Day = CurrentMealPlan[index] /// NO!
请记住,您在父视图中声明了 CurrentMealPlan
, 而不是 DailyMealPlan
视图。这意味着 DailyMealPlan
视图无法访问 CurrentMealPlan
.
但是,DailyMealPlan
视图 不需要 访问 CurrentMealPlan
。回到父视图,您已经循环遍历 CurrentMealPlan
并将每个 currentDay
传递给 DailyMealPlan
视图。
因此,您需要做的就是定义 DailyMealPlan
属性:
的类型
struct DailyMealPlan: View {
var DailyMealPlan: Day /// here!
...
}
这让编译器知道 var DailyMealPlan
接受了 Day
.
我建议使用 MVVM 方法,每个屏幕视图都应该有自己的视图模型(应该是 class 扩展基本视图模型或协议),您在创建视图时传递它。
在你的情况下你应该:
protocol BaseViewModel {
}
class DailyMealPlanViewModel: BaseViewModel {
@Published var day: Day
}
在上面我还添加了 day 作为 @Published 所以任何更改都会刷新视图,如果 day 永远不会改变您可以删除@Published。
在您看来:
struct DailyMealPlan: View {
@StateObject var viewModel: DailyMealPlanViewModel
...
...
导航时:
NavigationLink(
destination: DailyMealPlan(viewModel: DailyMealPlanViewModel(day: currentDay))
...
...
基本要点是我正在构建一个膳食计划应用程序。我是 Swift 和 SwiftUI 的新手,这是我的第一个项目,所以我可能犯了一个菜鸟错误大声笑基本上我想传递当前索引,这是一个数据当我点击相应的卡片时,一天的对象和它的膳食,到 DailyMealPlan 视图。当我将 currentDay 变量传递给视图时,我没有收到错误消息,但在第二个视图文件中,我不确定如何处理该数据。我不断收到“CurrentMealPlan 不在范围内”的错误消息。我了解范围的工作原理,我怀疑在将数据传递到第二个视图时我只是遗漏了一些东西。
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 视图
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")
}
}
}
}
}
当前膳食计划模型
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"
)
]
让我们浏览一下您的代码。首先,您在父视图中声明了 CurrentMealPlan
数组。它可能看起来像这样:
@State var CurrentMealPlan = [Day]()
注意:作为 var currentMealPlan
和 var dailyMealPlan
。此外,不应该 DailyMealPlan
视图和 DailyMealPlan
属性 具有相同的名称...这非常令人困惑。
您的代码是正确的。然后,您遍历 CurrentMealPlan
,并希望将每个元素传递给 DailyMealPlan
视图:
DailyMealPlan(DailyMealPlan: currentDay))
那也完全没问题。那么 CurrentMealPlan is not in scope
错误从何而来?就是这一行:
var DailyMealPlan: Day = CurrentMealPlan[index] /// NO!
请记住,您在父视图中声明了 CurrentMealPlan
, 而不是 DailyMealPlan
视图。这意味着 DailyMealPlan
视图无法访问 CurrentMealPlan
.
但是,DailyMealPlan
视图 不需要 访问 CurrentMealPlan
。回到父视图,您已经循环遍历 CurrentMealPlan
并将每个 currentDay
传递给 DailyMealPlan
视图。
因此,您需要做的就是定义 DailyMealPlan
属性:
struct DailyMealPlan: View {
var DailyMealPlan: Day /// here!
...
}
这让编译器知道 var DailyMealPlan
接受了 Day
.
我建议使用 MVVM 方法,每个屏幕视图都应该有自己的视图模型(应该是 class 扩展基本视图模型或协议),您在创建视图时传递它。
在你的情况下你应该:
protocol BaseViewModel {
}
class DailyMealPlanViewModel: BaseViewModel {
@Published var day: Day
}
在上面我还添加了 day 作为 @Published 所以任何更改都会刷新视图,如果 day 永远不会改变您可以删除@Published。
在您看来:
struct DailyMealPlan: View {
@StateObject var viewModel: DailyMealPlanViewModel
...
...
导航时:
NavigationLink(
destination: DailyMealPlan(viewModel: DailyMealPlanViewModel(day: currentDay))
...
...