[英]EnvironmentObject in TabView - SwiftUI
在我的應用程序中,我有一個費用清單。 我試圖讓我的 UserSettings 對象在我的 TabView 中鏈接的所有視圖中共享。
基本上,當 PayScheduleForm 中的 userSettings.date 更改時,我希望 ExpenseList 謂詞中的 userSettings.date 的值也發生更改。
我相信這樣做的方法是使用 EnvironmentObject。 當我啟動我的應用程序時,出現以下錯誤。 我已經看到了一些與此錯誤相關的鏈接,但似乎沒有一個可以解決我的問題。
Thread 1: Fatal error: No ObservableObject of type UserSettings found. A View.environmentObject(_:) for UserSettings may be missing as an ancestor of this view.
這是我當前的代碼:
SceneDelegate.swift
var window: UIWindow?
var settings = UserSettings()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = MainView().environment(\.managedObjectContext, coreDataStack.viewContext).environmentObject(settings)
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
主視圖.swift
import SwiftUI
import CoreData
@available(iOS 14.0, *)
struct MainView: View {
@EnvironmentObject var userSettings: UserSettings
@Environment(\.managedObjectContext)
var context: NSManagedObjectContext
var nextPaydate: Date{
return Calendar.current.date(byAdding: .day, value: 14, to: userSettings.date ) ?? Date()
}
var body: some View {
TabView {
DashboardView()
.tabItem {
VStack {
Text("Dashboard")
Image(systemName: "chart.pie")
}
}
.tag(0)
ExpenseList(predicate: NSPredicate(format: "expenseDate >= %@ AND expenseDate < %@", userSettings.date as NSDate, nextPaydate as NSDate), sortDescriptor: NSSortDescriptor(key: "expenseDate", ascending: true))
.tabItem {
VStack {
Text("Expense List")
Image(systemName: "list.dash")
}
}
.tag(1)
SettingsView()
.tabItem {
VStack {
Text("Settings")
Image(systemName: "gearshape")
}
}
.tag(2)
NewDashboard()
.tabItem {
VStack {
Text("TEST")
Image(systemName: "exclamationmark.square")
}
}
.tag(3)
}
.environmentObject(userSettings)
.onAppear(perform: changePayPeriod)
}
@available(iOS 14.0, *)
func changePayPeriod(){
let currentDate = Date()
if currentDate > PayScheduleForm().nextPaydate{
self.userSettings.date = PayScheduleForm().nextPaydate
}
}
}
@available(iOS 14.0, *)
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}
設置視圖.swift
import SwiftUI
import CoreData
struct SettingsView: View {
@State var accounts: String = ""
@Environment(\.managedObjectContext)
var context: NSManagedObjectContext
@EnvironmentObject var userSettings: UserSettings
var logToEdit: Accounts?
var body: some View {
NavigationView{
if #available(iOS 14.0, *) {
List{
NavigationLink(destination: AccountsList()) {
Text("Accounts")
}
NavigationLink(destination: CategoriesList()) {
Text("Categories")
}
NavigationLink(destination: PayScheduleForm()) {
Text("Pay Schedule")
}
}.navigationTitle("Settings")
} else {
// Fallback on earlier versions
}
}
.environmentObject(userSettings)
.onAppear(perform: {
getUserDefaults()
})
}
func getPayDate() -> Date{
var date = Date()
if UserDefaults.standard.object(forKey: "payDate") != nil {
date = UserDefaults.standard.object(forKey: "payDate") as! Date
}
let df = DateFormatter()
df.dateFormat = "MM/dd/yyyy"
print(df.string(from: date))
return date
}
func getUserDefaults(){
var date = Date()
if UserDefaults.standard.object(forKey: "payDate") != nil {
date = UserDefaults.standard.object(forKey: "payDate") as! Date
}
let df = DateFormatter()
df.dateFormat = "MM/dd/yyyy"
print(df.string(from: date))
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}
PayScheduleForm.swift
import SwiftUI
import CoreData
@available(iOS 14.0, *)
struct PayScheduleForm: View {
var frequencies = ["Bi-Weekly"]
@Environment(\.managedObjectContext) var context
@EnvironmentObject var userSettings : UserSettings
var currentPayDate: Date {
let calendar = NSCalendar.current
return calendar.startOfDay(for: userSettings.date) << Error shown here
}
var nextPaydate: Date{
return Calendar.current.date(byAdding: .day, value: 14, to: currentPayDate ) ?? Date()
}
var nextPaydateText: String{
return Utils.dateFormatterMed.string(from: nextPaydate)
}
var prevMonthPayStart: Date{
return Calendar.current.date(byAdding: .month, value: -1, to: currentPayDate ) ?? Date()
}
var prevMonthPayEnd: Date{
return Calendar.current.date(byAdding: .month, value: -1, to: nextPaydate ) ?? Date()
}
var prevMonthPayNextCheck: Date{
return Calendar.current.date(byAdding: .day, value: 14, to: prevMonthPayEnd ) ?? Date()
}
var prevWkPayStart: Date{
return Calendar.current.date(byAdding: .day, value: -7, to: currentPayDate ) ?? Date()
}
var body: some View {
Form{
TextField("Paycheck Amount", text: $userSettings.payAmount)
Picker(selection: $userSettings.frequency, label: Text("Pay Frequency")) {
ForEach(0 ..< frequencies.count) {
Text(self.frequencies[$0]).tag(userSettings.frequency)
}
}
DatePicker(selection: $userSettings.date, displayedComponents: .date) {
Text("Last Payday")
}
}.navigationTitle("Pay Settings")
Text("Next Payday: \(nextPaydateText)")
}
}
//struct PayScheduleForm_Previews: PreviewProvider {
// static var previews: some View {
// PayScheduleForm()
// }
//}
您的MainView
本地屬性隱藏了環境對象,因此只需將其刪除, userSettings
將作為注入的EnvironmentObject
可用
@available(iOS 14.0, *)
struct MainView: View {
// var userSettings = UserSettings() // << remove !!
@EnvironmentObject var userSettings: UserSettings // << add !!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.