Reputation: 14938
I just updated to Xcode 11.4 and it's broken my code. I am storing some user settings in an ObservableObject as follows:
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
}
This is my main menu, the settings environment object is successfully passed down to the Settings view where I'm able to save and retrieve user selections.
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")
}
}
}
}
}
But in my flashcard view, I am getting an error: Fatal error: No ObservableObject of type UserSettings found. A View.environmentObject(_:) for UserSettings may be missing as an ancestor of this view.: file SwiftUI, line 0
The error is on line 13 where I initiate Frontside. In the original code, I just called the Frontside subview, but I thought to solve the error I had to add .environmentObject(settings), but even after adding it my app compiles but crashes as soon I go to the Flashcard view.
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)
//
}
}
Does anyone know what I'm doing wrong? This code compiled and ran fine in the previous Xcode.
Upvotes: 3
Views: 5909
Reputation: 21
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)
}
}
}
Upvotes: 0
Reputation: 29242
An @EnvironmentObject
has to be filled with an @StateObject
, an @ObservedObject
or an ObservableObject
directly NOT an @State
struct ContentView: View {
//@ObservedObject
@StateObject var settings = UserSettings()
var body: some View {
SubView().environmentObject(settings)
}
}
Note: UserSettings
has to be an 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
// ...
}
Upvotes: 1
Reputation: 35
I'm running iOS 14.3 in the simulator and in my case the error was about my environmentObject NavigationController
. It was resolved by modifying ContentView()
with .environmentObject(NavigationController())
in the SceneDelegate
and, if you want the preview to work, also in ContentView_Previews
.
Upvotes: 1
Reputation: 5220
I think you should pass settings
object to FlashCard
and Settings
as well.
try this:
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")
}
}
}
}
}
Upvotes: 3