xcode - EnvironmentObject 使用 NavigationLink 刷新/移交问题
问题描述
我目前正在 macOS Catalina 上的 XCode 11.5 中使用 Swift/SwiftUI 为 watchOS 6(独立应用程序)开发应用程序。
在用户可以使用我的应用程序之前,需要一个配置过程。由于配置过程由几个不同的视图组成,这些视图一个接一个地显示,我通过使用导航链接实现了这一点。
配置过程完成后,用户应单击按钮返回“主”应用程序(主视图)。为了控制同一层级的视图,我的计划是结合“控制视图”使用 EnvironmentObject(据我了解,注入后的 EnvironmentObject 将移交给子视图,子视图可以使用 EnvironmentObject)它控制视图的显示。因此,我遵循了教程: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"
}
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")
}
}
}
}
AppMain.swift
struct AppMain: View {
var body: some View {
Text("Main App")
}
}
在我的代码的先前版本中(始终没有移交 EnvironmentObject)我得到一个运行时错误(“线程 1:致命错误:找不到 AppStateControl 类型的 ObservableObject。AppStateControl 的 View.environmentObject(_:) 可能作为该视图的祖先而丢失。”)由 AppConfig.swift 中的第 41 行引起。在互联网上,我读到这可能是 NavigationLink 的错误(参见:https ://www.hackingwithswift.com/forums/swiftui/environment-object-not-being-inherited-by-child-sometimes-and-app -崩溃/269,https://twitter.com/twostraws/status/1146315336578469888)。因此,建议将 EnvironmentObject 显式传递到 NavigationLink 的目的地(以上实现)。不幸的是,这也不起作用,而是单击“DetailView2”中的“Go to main App”按钮会导致视图“DetailView1”而不是“AppMain”。
任何想法如何解决这个问题?对我来说,通过导航链接调用的视图中 EnvironmentObject 的更改似乎不会刷新视图(正确)。
提前致谢。
解决方案
一种解决方案是创建一个变量来控制是否显示导航堆栈。
class AppStateControl: ObservableObject {
...
@Published var isDetailActive = false // <- add this
}
NavigationLink
然后你可以通过设置isActive
参数使用这个变量来控制第一个。您还需要添加.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
弹出所有 NavigationLinks 并返回主视图:
Button(action: {
self.appStateControl.callView = "AppMain"
self.appStateControl.isDetailActive = false // <- add this
}) {
Text("Go to main App")
}
推荐阅读
- javascript - 有没有办法在不转换大小写的情况下比较两个字符串?
- mysql - 如何使用 REGEX 提取字符串的一部分并将其添加到另一列然后分组?
- c++ - 如何用标准库替换 QByteArray?
- python - Python Django 在数据库上执行 save()
- python - Keras 模型输入的形状(尺寸)和类型错误
- google-app-engine - gcloud 应用程序部署在 AppEngine 标准环境中因超时而失败
- karate - 空手道 - 如何在被调用的功能中配置 afterScenario 挂钩?
- graphql - 解析 GraphQL 查询时出现语法错误。输入意外结束
- perl - 将变量从 shell 脚本传递到 Perl 脚本
- c# - 图是循环搜索