【发布时间】:2021-12-11 07:33:21
【问题描述】:
背景: 我已经被这个烦人的问题困住了好几天,尝试不同的解决方案并搜索stackoverflow等来寻找答案;有些人遇到过类似的问题,但没有建议的解决方案达到预期效果。
问题在于,当在导航层次视图堆栈中更新 observableObject 或 environmentObject 时,视图会弹出回根目录。从 observableObject 查看数据很好,但不能编辑。
场景是:
- 我导航到:root -> view1 -> view2。
- 我在 View2 中更新了 environmentObject,但随后又被推回到:root -> view1
我已经简化了我的应用程序以使其更易于理解。见下文:
ObservableObject:
class DataStore: ObservableObject {
static let shared = dataStore()
@Published var name : String = ""
}
根视图:
struct ContentView: View {
@StateObject var dataStore = DataStore.shared
@State private var isShowingView1 = false
var body: some View {
NavigationView{
VStack{
Text(dataStore.name)
NavigationLink(destination: View1(), isActive: $isShowingView1) { }
Button(action: {
isShowingView1 = true
})
}
}
}
}
视图1:
struct View1: View {
@EnvironmentObject var dataStore: dataStore
@State private var isShowingView2 = false
var body: some View {
ScrollView{
VStack(alignment: .center) {
Text(dataStore.name)
NavigationLink(destination: View2(), isActive: $isShowingView2) { }
Button(action: {
isShowingView2 = true
}){
Text("Go to View2")
}
}
}
}
}
视图2:
struct View2: View {
@EnvironmentObject var dataStore: dataStore
var body: some View {
ScrollView{
VStack(alignment: .center) {
Text(dataStore.name)
Button(action: {
dataStore.name = "updated value"
}){
Text("Update data")
}
// When updating this environmentObject the viewstack will be pushed back to View1. If view2 had been navigated to view3 and the view3 had been updating the environmentObject, then it would also be pushed back to View1.
}
}
}
}
解决方案: 我花了很多时间寻找解决方案并尝试不同的方法,但我尝试过的都没有奏效。似乎还有其他一些人遇到了与我相同的问题,但建议的解决方案并没有解决问题。 但是后来我在尝试实现另一个功能时偶然发现了这个问题的解决方案。所以坦率地说,我现在写在这里,不是向这个伟大的社区寻求帮助,而是通过向可能需要看到这个的其他人提供这个解决方案来回馈社区。p>
解决方案非常简单,但并不容易遇到。如果您遇到与我类似的问题,那么您只需要相应地更新您的 rootView:
RootView 更新:
struct ContentView: View {
@StateObject var dataStore = DataStore.shared
@State private var isShowingView1 = false
var body: some View {
NavigationView{
VStack{
Text(dataStore.name)
NavigationLink(destination: View1(), isActive: $isShowingView1) { }
Button(action: {
isShowingView1 = true
})
}
}
.navigationViewStyle(.stack)
//ADD THIS LINE ABOVE
}
}
这一行 .navigationViewStyle(.stack) 为我解决了弹出视图堆栈的问题。不幸的是,我无法为您提供这种行为的逻辑解释,但它有效,我对此感到满意。也许您也是如此,或者您可能已经了解为什么此解决方案实际上实现了允许层次结构向下的视图更新 observableObjects 而不会被弹出的预期效果。
【问题讨论】:
-
既然您似乎已经有了答案,您应该更新您的问题,使其仅包含问题,然后自己添加答案。然后,您可以在 2 天后将其标记为已接受。
-
iOS 14 怎么样?由于 .stack 在 iOS 13 和 14 中不可用。
-
你确定吗?根据该站点developer.apple.com/documentation/swiftui/navigationviewstyle/…,navigationView 的 .Stack 视图样式似乎从 iOS 13.0 开始可用。根据这个网站developer.apple.com/support/app-store 90% 的设备是 iOS 14.0 及更高版本。所以我认为这个解决方案应该涵盖它。或者您还有其他我遗漏的信息吗?
标签: swift swiftui swiftui-navigationlink swiftui-navigationview swiftui-environment