【问题标题】:SwiftUI NavigationView pops back when updating observableObject更新 observableObject 时 SwiftUI NavigationView 弹回
【发布时间】:2021-12-11 07:33:21
【问题描述】:

背景: 我已经被这个烦人的问题困住了好几天,尝试不同的解决方案并搜索stackoverflow等来寻找答案;有些人遇到过类似的问题,但没有建议的解决方案达到预期效果。

问题在于,当在导航层次视图堆栈中更新 observableObject 或 environmentObject 时,视图会弹出回根目录。从 observableObject 查看数据很好,但不能编辑。

场景是:

  1. 我导航到:root -> view1 -> view2。
  2. 我在 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 而不会被弹出的预期效果。

【问题讨论】:

标签: swift swiftui swiftui-navigationlink swiftui-navigationview swiftui-environment


【解决方案1】:

解决方案非常简单,但并不容易遇到。如果您遇到与我类似的问题,那么您只需要相应地更新您的 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) 为我解决了弹出视图堆栈的问题。不幸的是,我无法为您提供这种行为的逻辑解释,但它确实有效,我对此感到满意。

【讨论】:

猜你喜欢
  • 2020-12-05
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多