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.
,我通过简单地忽略该对象中的任何位置更新来在代码中做到这一点
效果很好。
所以不是这个:
我做到了
一共有三种观点。主视图、列表视图(显示位置列表)和内容视图(显示单个位置)。列表视图和内容视图都在监视 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.
,我通过简单地忽略该对象中的任何位置更新来在代码中做到这一点效果很好。
所以不是这个:
我做到了