我目前正在macOS Catalina上使用XCode 11.5中的Swift/SwiftUI为watchOS 6(独立应用程序(开发应用程序。
在用户可以使用我的应用之前,需要进行配置过程。由于配置过程由几个不同的视图组成,这些视图一个接一个地显示,因此我使用导航链接实现了这一点。
配置过程完成后,用户应单击按钮以返回到"主"应用程序(主视图(。为了控制处于同一层次结构级别的视图,我的计划是使用环境对象(据我所知,一旦注入环境对象就会移交给子视图,子视图可以使用环境对象(与控制视图显示的"控制视图"结合使用。因此,我遵循了教程:https://blckbirds.com/post/how-to-navigate-between-views-in-swiftui-by-using-an-environmentobject/
这是我的代码:
内容视图.swift
struct ContentView: View {
var body: some View {
ContentViewManager().environmentObject(AppStateControl())
}
}
struct ContentViewManager: View {
@EnvironmentObject var appStateControl: AppStateControl
var body: some View {
VStack {
if(appStateControl.callView == "AppConfig") {
AppConfig()
}
if(appStateControl.callView == "AppMain") {
AppMain()
}
}
}
}
AppStateControl.swift
class AppStateControl: ObservableObject {
@Published var callView: String = "AppConfig"
}
应用配置.swift
struct AppConfig: View {
@EnvironmentObject var appStateControl: AppStateControl
var body: some View {
VStack {
Text("App Config Main")
NavigationLink(destination: DetailView1().environmentObject(appStateControl)) {
Text("Show Detail View 1")
}
}
}
}
struct DetailView1: View {
@EnvironmentObject var appStateControl: AppStateControl
var body: some View {
VStack {
Text("App Config Detail View 1")
NavigationLink(destination: DetailView2().environmentObject(appStateControl)) {
Text("Show Detail View 2")
}
}
}
}
struct DetailView2: View {
@EnvironmentObject var appStateControl: AppStateControl
var body: some View {
VStack {
Text("App Config Detail View 2")
Button(action: {
self.appStateControl.callView = "AppMain"
}) {
Text("Go to main App")
}
}
}
}
应用主.swift
struct AppMain: View {
var body: some View {
Text("Main App")
}
}
在我的代码的早期版本中(没有一直移交环境对象(,我收到一个运行时错误("线程 1:致命错误:找不到 AppStateControl 类型的可观察对象。AppStateControl 的 View.environmentObject(_:( 可能作为此视图的祖先缺失.swift。在互联网上,我读到这可能是NavigationLink的一个错误(参见:https://www.hackingwithswift.com/forums/swiftui/environment-object-not-being-inherited-by-child-sometimes-and-app-crashes/269,https://twitter.com/twostraws/status/1146315336578469888(。因此,建议将环境对象显式传递到导航链接的目标(上述实现(。不幸的是,这也不起作用,而是单击"DetailView2"中的"转到主应用程序"按钮会导致视图">DetailView1">而不是"AppMain"。
有什么想法可以解决这个问题吗?对我来说,似乎通过导航链接调用的视图中环境对象的更改不会刷新视图(正确(。
提前谢谢。
解决方案之一是创建一个变量,控制是否显示导航堆栈。
class AppStateControl: ObservableObject {
...
@Published var isDetailActive = false // <- add this
}
然后,您可以使用此变量通过设置isActive
参数来控制第一个NavigationLink
。此外,您还需要向所有后续链接添加.isDetailLink(false)
。
堆栈中的第一个链接:
NavigationLink(destination: DetailView1().environmentObject(appStateControl), isActive: self.$appStateControl.isDetailActive) {
Text("Show Detail View 1")
}
.isDetailLink(false)
所有其他链接:
NavigationLink(destination: DetailView2().environmentObject(appStateControl)) {
Text("Show Detail View 2")
}
.isDetailLink(false)
然后只需将isDetailActive
设置为false
即可弹出所有导航链接并返回主视图:
Button(action: {
self.appStateControl.callView = "AppMain"
self.appStateControl.isDetailActive = false // <- add this
}) {
Text("Go to main App")
}