当在 onChange 上获取数据并使用 ForEach 显示时,用户导航到父屏幕
User navigated to Parent screen when data fetched on onChange and displayed using ForEach
View1 有一个运行计时器的 StateObject。当满足计时器条件时,将调用 Views1 的 onChange() 以重新获取数据。此数据使用 ForEach 显示。
在 ForEach 内部,我们有指向 View2 的 NavigationLink。假设用户现在在 View2 屏幕中。
但是只要在 View1 上满足时间条件,即使用户在 View2 屏幕中,也会显示 View1。
为什么是这样?这在没有 ForEach 的情况下有效。
Foreach 是问题所在吗?可以做些什么来让用户停留在任何屏幕上?
谢谢
Github 显示问题的代码:https://github.com/Kavisha-Dev/BackToParentPageIssue
在 CotentView
试试这个:
struct ContentView: View {
@StateObject var todayMealStore: TodayMealStore = TodayMealStore()
@StateObject private var evilObject = TimerStateObject()
@State var index = 0
@State var stopTimer = false
var body: some View {
NavigationView {
VStack {
if todayMealStore.todaysMeals.count > 0 {
NavigationLink(destination: SampleView01(mealCategoryName: todayMealStore.todaysMeals[0].name)) {
Text("Single Object: Tap me : \(todayMealStore.todaysMeals[0].name)")
.foregroundColor(.green)
}.padding()
}
/*iOS < 15 //don't forget to uncomment the code you require
ForEach(todayMealStore.todaysMeals) { item in
NavigationLink(destination: SampleView01(mealCategoryName: item.name), isActive: getBinding(item)) {
Text("ForEach item: Tap me : \(item.name)")
.foregroundColor(.green)
}.padding()
}*/
/*iOS > 15
ForEach($todayMealStore.todaysMeals) { $item in
NavigationLink(destination: SampleView01(mealCategoryName: item.name), isActive: $item.stopTimer) {
Text("ForEach item: Tap me : \(item.name)")
.foregroundColor(.green)
}.padding()
}*/
NavigationLink(destination: SampleView02(name: "Another View")) {
Text("Tap me")
} .padding()
}.onAppear(perform: fetchTodaysMeals)
.onChange(of: evilObject.changedNumber) { newValue in
if !todayMealStore.todaysMeals.contains(where: {[=10=].stopTimer}) {
print("ContentView: onChange hit. New Meal Data fetched!")
fetchTodaysMeals()
}
}.onChange(of: todayMealStore.todaysMeals.contains(where: {[=10=].stopTimer})) { newValue in
if !newValue {
fetchTodaysMeals()
}
}
}
}
func fetchTodaysMeals() {
todayMealStore.fetch()
}
func getBinding(_ item: TodayMealModel) -> Binding<Bool> { //for iOS < 15
return Binding {
item.stopTimer
} set: { value in
todayMealStore.todaysMeals[todayMealStore.todaysMeals.firstIndex(where: {[=10=].id == item.id}) ?? 0].stopTimer = value
}
}
}
今日膳食模型:
struct TodayMealModel: Identifiable {
public var id: UUID = UUID()
var mealId: UUID
var name: String
var stopTimer = false
}
基本上我所做的是在 NavigationLink
处于活动状态时阻止计时器刷新,当 NavigationLink
被关闭时,视图会自动刷新。
您还可以完全停止计时器,而不是停止执行刷新功能。
至于为什么会出现这种情况,因为视图不断刷新,传递的视图(SampleView01
)取决于正在刷新的数据,因此它会被关闭。
View1 有一个运行计时器的 StateObject。当满足计时器条件时,将调用 Views1 的 onChange() 以重新获取数据。此数据使用 ForEach 显示。
在 ForEach 内部,我们有指向 View2 的 NavigationLink。假设用户现在在 View2 屏幕中。
但是只要在 View1 上满足时间条件,即使用户在 View2 屏幕中,也会显示 View1。 为什么是这样?这在没有 ForEach 的情况下有效。
Foreach 是问题所在吗?可以做些什么来让用户停留在任何屏幕上? 谢谢
Github 显示问题的代码:https://github.com/Kavisha-Dev/BackToParentPageIssue
在 CotentView
试试这个:
struct ContentView: View {
@StateObject var todayMealStore: TodayMealStore = TodayMealStore()
@StateObject private var evilObject = TimerStateObject()
@State var index = 0
@State var stopTimer = false
var body: some View {
NavigationView {
VStack {
if todayMealStore.todaysMeals.count > 0 {
NavigationLink(destination: SampleView01(mealCategoryName: todayMealStore.todaysMeals[0].name)) {
Text("Single Object: Tap me : \(todayMealStore.todaysMeals[0].name)")
.foregroundColor(.green)
}.padding()
}
/*iOS < 15 //don't forget to uncomment the code you require
ForEach(todayMealStore.todaysMeals) { item in
NavigationLink(destination: SampleView01(mealCategoryName: item.name), isActive: getBinding(item)) {
Text("ForEach item: Tap me : \(item.name)")
.foregroundColor(.green)
}.padding()
}*/
/*iOS > 15
ForEach($todayMealStore.todaysMeals) { $item in
NavigationLink(destination: SampleView01(mealCategoryName: item.name), isActive: $item.stopTimer) {
Text("ForEach item: Tap me : \(item.name)")
.foregroundColor(.green)
}.padding()
}*/
NavigationLink(destination: SampleView02(name: "Another View")) {
Text("Tap me")
} .padding()
}.onAppear(perform: fetchTodaysMeals)
.onChange(of: evilObject.changedNumber) { newValue in
if !todayMealStore.todaysMeals.contains(where: {[=10=].stopTimer}) {
print("ContentView: onChange hit. New Meal Data fetched!")
fetchTodaysMeals()
}
}.onChange(of: todayMealStore.todaysMeals.contains(where: {[=10=].stopTimer})) { newValue in
if !newValue {
fetchTodaysMeals()
}
}
}
}
func fetchTodaysMeals() {
todayMealStore.fetch()
}
func getBinding(_ item: TodayMealModel) -> Binding<Bool> { //for iOS < 15
return Binding {
item.stopTimer
} set: { value in
todayMealStore.todaysMeals[todayMealStore.todaysMeals.firstIndex(where: {[=10=].id == item.id}) ?? 0].stopTimer = value
}
}
}
今日膳食模型:
struct TodayMealModel: Identifiable {
public var id: UUID = UUID()
var mealId: UUID
var name: String
var stopTimer = false
}
基本上我所做的是在 NavigationLink
处于活动状态时阻止计时器刷新,当 NavigationLink
被关闭时,视图会自动刷新。
您还可以完全停止计时器,而不是停止执行刷新功能。
至于为什么会出现这种情况,因为视图不断刷新,传递的视图(SampleView01
)取决于正在刷新的数据,因此它会被关闭。