View.environmentObject(_:) for 可能作为该视图的祖先而丢失
Posted
技术标签:
【中文标题】View.environmentObject(_:) for 可能作为该视图的祖先而丢失【英文标题】:A View.environmentObject(_:) for may be missing as an ancestor of this view 【发布时间】:2020-03-28 08:34:04 【问题描述】:我刚刚更新到 Xcode 11.4,它破坏了我的代码。我将一些用户设置存储在 ObservableObject 中,如下所示:
class UserSettings: ObservableObject
@Published var cardOrder = UserDefaults.standard.integer(forKey: "Card Order")
@Published var cardTheme = UserDefaults.standard.integer(forKey: "Card Theme")
@Published var translation = UserDefaults.standard.integer(forKey: "Translation")
@Published var overdueFirst = UserDefaults.standard.bool(forKey: "Overdue First")
@Published var randomNum = 0
这是我的主菜单,设置环境对象已成功传递到设置视图,我可以在其中保存和检索用户选择。
struct ContentView: View
@State var settings = UserSettings()
var body: some View
SubView().environmentObject(settings)
struct SubView: View
@EnvironmentObject var settings: UserSettings
var body: some View
List
NavigationLink (destination: Flashcard())
HStack
Image(systemName: "rectangle.on.rectangle.angled")
Text(verbatim: "Study")
NavigationLink (destination: Settings())
HStack
Image(systemName: "gear")
Text(verbatim: "Settings")
但在我的抽认卡视图中,我收到一个错误:致命错误:未找到 UserSettings 类型的 ObservableObject。 UserSettings 的 View.environmentObject(_:) 作为此视图的祖先可能会丢失。:文件 SwiftUI,第 0 行
错误出现在我启动 Frontside 的第 13 行。在原始代码中,我只是调用了 Frontside 子视图,但我想解决这个错误,我必须添加 .environmentObject(settings),但即使添加了它,我的应用程序也会编译,但一进入 Flashcard 视图就会崩溃。
struct Flashcard: View
@EnvironmentObject var settings: UserSettings
@State var colour = UserDefaults.standard.integer(forKey: "Card Theme") * 6
@State private var showResults: Bool = false
@State private var fullRotation: Bool = false
@State private var showNextCard: Bool = false
var body: some View
let zstack = ZStack
Frontside(id: $settings.randomNum, sheet: $showingSheet, rotate: $fullRotation, invis: $showNextCard, col: $colour).environmentObject(self.settings)
//
Backside(id: $settings.randomNum, sheet: $showingSheet, bookmark: $bookmarked, results: $showResults, rotate: $fullRotation, invis: $showNextCard, col: $colour, trans: $translation).environmentObject(self.settings)
//
有谁知道我做错了什么?此代码在之前的 Xcode 中编译并运行良好。
【问题讨论】:
这里的问题完全相同。应用程序在升级到 13.4 之前正在修复:/ 不过,它在模拟器上运行良好。它只会在设备上崩溃。你也一样? 不,我的模拟器也崩溃了。该应用程序加载正常,但是当我转到此特定视图时,它崩溃了。但我不知道出了什么问题,因为我有其他使用该环境对象的子视图并且它们没有崩溃。 【参考方案1】:我认为您也应该将settings
对象传递给FlashCard
和Settings
。
试试这个:
struct ContentView: View
@State var settings = UserSettings()
var body: some View
SubView().environmentObject(settings)
struct SubView: View
@EnvironmentObject var settings: UserSettings
var body: some View
List
NavigationLink (destination: Flashcard().environmentObject(settings))
HStack
Image(systemName: "rectangle.on.rectangle.angled")
Text(verbatim: "Study")
NavigationLink (destination: Settings().environmentObject(settings))
HStack
Image(systemName: "gear")
Text(verbatim: "Settings")
【讨论】:
为什么这是必要的呢?传递给祖先视图(即“子视图”)的 environmentObject 不应该被后代视图(即闪存卡和设置)自动访问吗?与直接作为 Flashcard/Settings 视图的属性传递相比,这种方法给我们带来了什么好处?【参考方案2】:@EnvironmentObject
必须直接填充 @StateObject
、@ObservedObject
或 ObservableObject
而不是 @State
struct ContentView: View
//@ObservedObject
@StateObject var settings = UserSettings()
var body: some View
SubView().environmentObject(settings)
注意:UserSettings
必须是 ObservableObject
Apple documentation on managing model data
struct BookReader: App
@StateObject var library = Library()
var body: some Scene
WindowGroup
LibraryView()
.environmentObject(library)
struct LibraryView: View
@EnvironmentObject var library: Library
// ...
【讨论】:
【参考方案3】:我在模拟器中运行 ios 14.3,在我的情况下,错误是关于我的 environmentObject NavigationController
。通过在SceneDelegate
中修改ContentView()
和.environmentObject(NavigationController())
解决了这个问题,如果您希望预览工作,也可以在ContentView_Previews
中进行。
【讨论】:
【参考方案4】:import SwiftUI
@main
// there is a file with the name of your "projectApp" (JuegosSwiftUIApp in my case)
struct JuegosSwiftUIApp: App
var body: some Scene
WindowGroup
DatosIniciales() // any view
.environmentObject(Datos()) // this solved it (Datos() is class type Observableobject)
【讨论】:
虽然此代码可以回答问题,但提供有关 如何 和/或 为什么 解决问题的附加上下文将改善答案的长期价值。【参考方案5】:去掉 let zstack =
ZStack
Frontside(id: $settings.randomNum, sheet: $showingSheet, rotate: $fullRotation, invis: $showNextCard, col: $colour).environmentObject(self.settings)
//
Backside(id: $settings.randomNum, sheet: $showingSheet, bookmark: $bookmarked, results: $showResults, rotate: $fullRotation, invis: $showNextCard, col: $colour, trans: $translation).environmentObject(self.settings)
//
【讨论】:
以上是关于View.environmentObject(_:) for 可能作为该视图的祖先而丢失的主要内容,如果未能解决你的问题,请参考以下文章