SwiftUI @EnvironmentObject error: may be missing as an ancestor of this view
The whole issue is very easy to fix just add self.networkManager @ EarthQuakeList.swift
.sheet(isPresented: $showEditPage) {
return EditPage().environmentObject(self.networkManager)
I got the reason and inspired from article:
https://github.com/peterfriese/Swift-EnvironmentObject-Demo
SwiftUI @EnvironmentObject error: may be missing as an ancestor of this view -- accessing object in the init()
The answer is that an Environment Object apparently cannot be accessed in an init() function. However, an ObservedObject can be. So I changed the code to this and it works. To make it easy I turned TState into a singleton that I could access anywhere. This could probably replace the use of @EnvironmentObject in many situations.
struct TEditorView: View {
@ObservedObject private var tState = TState.shared
//@EnvironmentObject private var tState: TState
@State var name = ""
init() {
self._name = State(initialValue: tState.name)
}
var body: some View {
...
}
}
A View.environmentObject(_:) may be missing as an ancestor of this view - but not always…
The reason your problem is intermittent, is probably because the PurchaseManager
init()
could finish
before all the data is setup properly, due to the "delays" of the
async functions in init()
. So sometimes the data will be available
when the View wants it, and sometimes it will not be there and crash your app.
You could try the following approach that includes @atultw advice of using
StateObject.
import SwiftUI
@main
struct TestApp: App {
@StateObject var purchaseManager = PurchaseManager() // <-- here
var body: some Scene {
WindowGroup {
MainView()
.onAppear {
purchaseManager.startMeUp() // <-- here
}
.environmentObject(purchaseManager)
}
}
}
struct MainView: View {
@EnvironmentObject var purchaseManager: PurchaseManager
var body: some View {
Text("testing")
List {
ForEach(purchaseManager.offerings, id: \.self) { offer in
Text(offer)
}
}
}
}
public class PurchaseManager: ObservableObject {
@Published var offerings: [String] = []
// -- here --
func startMeUp() {
// setupRevenueCat()
fetchOfferings()
// refreshPurchaserInfo()
}
func fetchOfferings() {
DispatchQueue.main.asyncAfter(deadline: .now()+2) {
self.offerings = ["offer 1","offer 2","offer 3","offer 4"]
}
}
}
A View.environmentObject(_:) for AppInformation may be missing as an ancestor of this view
So first of all, your example code is not working.
- Use
@Published
for your properties, then useSlider(value: $appInfo.duration, ...)
. This is becauseSlider
is expecting a Binding (see https://developer.apple.com/documentation/swiftui/slider) - Use the
struct Settings_Previews
outside ofstruct Settings
Below you will find the fixed version. Both running in previews and in Simulator.
To answer your question:
If you use Settings
anywhere in your Code, you have to pass it an environmentObject of AppInformation
(See ContentView
). Since you did not provide any source code in context I assume thats where your error is.
Here is a working example:
import SwiftUI
import CoreData
class AppInformation: ObservableObject {
@Published var duration = 0.0
@Published var interval = 0.0
}
struct Settings: View {
@EnvironmentObject var appInfo: AppInformation
var body: some View {
NavigationView {
ZStack {
VStack (spacing: 35){
HStack {
Text("Duration")
.font(.system(size: 23, weight: .bold, design: .rounded))
.padding(.leading, 25)
Spacer()
Slider(value: $appInfo.duration, in: 1...60, step: 1)
.padding([.trailing, .leading], 20)
Text("\(Int(appInfo.duration))")
.padding(.trailing, 30)
.font(.system(size: 23, weight: .medium, design: .rounded))
}
.padding(.top, 100)
HStack {
Text("Interval ")
.font(.system(size: 23, weight: .bold, design: .rounded))
.padding(.leading, 25)
Spacer()
Slider(value: $appInfo.interval, in: 1...60, step: 1)
.padding([.trailing, .leading], 20)
Text("\(Int(appInfo.interval))")
.padding(.trailing, 30)
.font(.system(size: 23, weight: .medium, design: .rounded))
}
Spacer()
}
}
.navigationTitle("Settings")
}
}
}
struct Settings_Previews: PreviewProvider {
static var previews: some View {
Settings()
.environmentObject(AppInformation())
}
}
struct ContentView: View {
@ObservedObject var appInformation = AppInformation()
var body: some View {
Settings()
.environmentObject(appInformation)
}
}
Also here are some tips using SwiftUI
:
- If you need to set padding on multiple edges you can use also use
.padding([.trailing, .leading], 20)
- You should set the
.navigationTitle("Settings")
modifier on the outer child of the view - but within theNavigationView
- You can also set the
.font
modifier on theVStack
orHStack
, this would apply it to all children (including the Slider Label)
No ObservableObject of type CarouselViewModel found. A View.environmentObject(_:) for CarouselViewModel may be missing as an ancestor of this view
Wherever you instantiate the Home
view, you have to add an .environmentObject
modifier that passes an instance of CarouselViewModel
to it.
I don't know what your exact code looks like (or what CarouselViewModel
takes as parameters), but it'll look something like:
//somewhere in the parent view:
@StateObject private var model = CarouselViewModel() //if iOS 13, use @ObservedObject
//where you instantiate `Home`:
Home().environmentObject(model)
Note that this will also be an error if you try to use Home
in a SwiftUI Preview and it doesn't have this .environmentObject
code.
SwiftUI Fatal error: No ObservableObject of type AppData found. A View.environmentObject(_:) for AppData may be missing as an ancestor of this view
EnvironmentObjects must be supplied by anscestor views!
@main
struct WFT_demo2App: App {
var body: some Scene {
WindowGroup {
ContentView(text: .constant(""))
.environmentObject(AppData()) // <<: Here!
}
}
}
Related Topics
Dispatchqueue:Cannot Be Called with Ascopy = No on Non-Main Thread
Xcode Error: Missing Required Module 'Firebase'
Enumerateobjectsusingblock in Swift
Swift Calling Static Methods: Type(Of: Self) VS Explicit Class Name
Swift Struct Doesn't Conform to Protocol Equatable
Why Is There a Memory Leak at String Creation in Swift
Uialertcontroller Change Font Color
What's the Swift Equivalent of Objective-C's "#Ifdef _Iphone_11_0"
Swift Tableview Cell Set Accessory Type
How to Add Caching to Asyncimage
How to Select a Contact with Abpeoplepickernavigationcontroller in Swift
Swift - Take Nil as Argument in Generic Function with Optional Argument
Swift: Dictionary Access via Index
Switch That Checks Nsindexpath's Row and Section
Xcode 11 Doesn't Recognize Core Data Entity
Swiftui: How to Iterate Over an Array of Bindable Objects