缺少视图作为视图的祖先
A view is missing as an ancestor of a view
我有一个 login.swift
主要是:
import SwiftUI
class GlobalEnvironment: ObservableObject {
@Published var accountId: Int = 0
}
struct Login: View {
@EnvironmentObject var env: GlobalEnvironment
@State private var username: String = ""
@State private var password: String = ""
@State var authenticationDdidFail: Bool = false
@State var authenticationDidSucceed: Bool = false
var body: some View {
if env.accountId == 0 {
return AnyView(LoginView(username: self.$username, password: self.$password, authenticationDdidFail: self.$authenticationDdidFail, authenticationDidSucceed: self.$authenticationDidSucceed))
} else {
return AnyView(ContentView().environmentObject(GlobalEnvironment()))
}
}
}
...
该文件在登录后设置 env.accontId
,并且在 LoginView 中成功。
然后我有一个 data.swit
有:
struct Transaction: Codable, Identifiable {
let id = UUID()
var purpose: String
}
class Api {
@EnvironmentObject var env: GlobalEnvironment
func getTransactions(completion: @escaping ([Transaction]) -> ()) {
guard let url = URL(string: "https://url.com/api.php?get_transactions&account=\(env.accountId)") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
let transactions = try! JSONDecoder().decode([Transaction].self, from: data!)
DispatchQueue.main.async {
completion(transactions)
}
}
.resume()
}
API 从 Transactions.swift
调用:
import SwiftUI
struct ContentView: View {
@EnvironmentObject var env: GlobalEnvironment
@State var transactions: [Transaction] = []
var body: some View {
NavigationView {
List(transactions) { transaction in
Text(transaction.purpose)
}
.environmentObject(GlobalEnvironment())
.onAppear {
Api().getTransactions { (transactions) in
self.transactions = transactions
}
}
.navigationBarTitle(Text("Transactions"))
}
}
}
我收到 guard let url = URL(string: "https://url.com/api.php?get_transactions&account=\(env.accountId)") else { return }
的错误 Thread 1: Fatal error: No ObservableObject of type GlobalEnvironment found. A View.environmentObject(_:) for GlobalEnvironment may be missing as an ancestor of this view.
。
根据我的理解,将 GlobalEnvironment 添加到 Api class,应该可以,但没有。相反,我已经尝试将它添加到函数中,但它也不起作用。如您所见,将 .environmentObject() 添加到列表视图本身也是如此。
必须是:
.environmentObject(self.env)
当然,在 SceneDelegate 或其他地方可能还有更多错误。
你可以尝试在 onAppear
的电话中发送你的 environmentObject
.onAppear
{
Api().getTransactions { (transactions) in
self.transactions = transactions
}.environmentObject(self.env)
}
我有一个 login.swift
主要是:
import SwiftUI
class GlobalEnvironment: ObservableObject {
@Published var accountId: Int = 0
}
struct Login: View {
@EnvironmentObject var env: GlobalEnvironment
@State private var username: String = ""
@State private var password: String = ""
@State var authenticationDdidFail: Bool = false
@State var authenticationDidSucceed: Bool = false
var body: some View {
if env.accountId == 0 {
return AnyView(LoginView(username: self.$username, password: self.$password, authenticationDdidFail: self.$authenticationDdidFail, authenticationDidSucceed: self.$authenticationDidSucceed))
} else {
return AnyView(ContentView().environmentObject(GlobalEnvironment()))
}
}
}
...
该文件在登录后设置 env.accontId
,并且在 LoginView 中成功。
然后我有一个 data.swit
有:
struct Transaction: Codable, Identifiable {
let id = UUID()
var purpose: String
}
class Api {
@EnvironmentObject var env: GlobalEnvironment
func getTransactions(completion: @escaping ([Transaction]) -> ()) {
guard let url = URL(string: "https://url.com/api.php?get_transactions&account=\(env.accountId)") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
let transactions = try! JSONDecoder().decode([Transaction].self, from: data!)
DispatchQueue.main.async {
completion(transactions)
}
}
.resume()
}
API 从 Transactions.swift
调用:
import SwiftUI
struct ContentView: View {
@EnvironmentObject var env: GlobalEnvironment
@State var transactions: [Transaction] = []
var body: some View {
NavigationView {
List(transactions) { transaction in
Text(transaction.purpose)
}
.environmentObject(GlobalEnvironment())
.onAppear {
Api().getTransactions { (transactions) in
self.transactions = transactions
}
}
.navigationBarTitle(Text("Transactions"))
}
}
}
我收到 guard let url = URL(string: "https://url.com/api.php?get_transactions&account=\(env.accountId)") else { return }
的错误 Thread 1: Fatal error: No ObservableObject of type GlobalEnvironment found. A View.environmentObject(_:) for GlobalEnvironment may be missing as an ancestor of this view.
。
根据我的理解,将 GlobalEnvironment 添加到 Api class,应该可以,但没有。相反,我已经尝试将它添加到函数中,但它也不起作用。如您所见,将 .environmentObject() 添加到列表视图本身也是如此。
必须是:
.environmentObject(self.env)
当然,在 SceneDelegate 或其他地方可能还有更多错误。
你可以尝试在 onAppear
environmentObject
.onAppear
{
Api().getTransactions { (transactions) in
self.transactions = transactions
}.environmentObject(self.env)
}