SwiftUI NavigationView 在观察到的对象发生变化时弹出

SwiftUI NavigationView popping when observed object changes

一共有三种观点。主视图、列表视图(显示位置列表)和内容视图(显示单个位置)。列表视图和内容视图都在监视 LocationManager(GPS 位置)的变化。

如果用户从列表视图导航到内容视图,然后观察到的 LocationManager 发生变化,则弹出 ContentView 并显示列表视图。

我将 NavigationViewStyle 设置为 .stack(有些人发现这有帮助)但没有效果。

有谁知道我做错了什么吗?

// 主视图

@StateObject var locations = Locations()
    var body: some Scene {
        WindowGroup {
            TabView(){
                NavigationView {
                    ListView()
                }.navigationViewStyle(.stack).tabItem {
                    Text("List")
                }
            }.environmentObject(locations)
        }
    }

// 列表视图

@EnvironmentObject var locations: Locations
@ObservedObject private var locationManager = LocationManager()

  var body: some View {
            List(){
                ForEach(locations, id: \.id) {
                    loc in
                        NavigationLink(destination: ContentView(location: loc, locationManager: locationManager)) {
                            Text(loc.name)
                        }.isDetailLink(false)
                }
            }.listStyle(PlainListStyle())
        }.navigationTitle("List")

// Content/Detail 查看

   let location: Location
   let locationManager: LocationManager

   var body: some View { Text("I am detail") }

它弹出是因为您的对象不是唯一的。想想这个:

您在一个名为 Alen 的视图中,现在您刷新该视图,它被称为 Alenx,SwiftUI 会弹出您回来,因为数据不同。

让它保持不变的方法是使元素独一无二 (Identifiable),为此你可以为你的模型分配一些独一无二的 id,这里有一种方法:

struct Example: Identifiable {
    
    let id = UUID()
    
    var someValue: String
    
    private enum CodingKeys: String, CodingKey { case someValue }
}

我最后做的是有两个可观察对象,一个用于列表,一个用于细节。

可观察对象是 GPS 坐标,因此当显示内容视图时(您可以通过在视图的 onAppear 中添加状态来跟踪它)您不允许更改列表的可观察对象.

换句话说,如果内容视图可见,则列表视图具有的可观察对象不会改变。如果当前视图是 Content/Detail.

,我通过简单地忽略该对象中的任何位置更新来在代码中做到这一点

效果很好。

所以不是这个:

我做到了