2

我在DateView中有一个像这样声明的 ObservableObject :

import SwiftUI

    class SelectedDate: ObservableObject {
        @Published var selectedMonth: Date = Date()
        
        var startDateOfMonth: Date {
            let components = Calendar.current.dateComponents([.year, .month], from: self.selectedMonth)
            let startOfMonth = Calendar.current.date(from: components)!
            return startOfMonth
        }
    
        var endDateOfMonth: Date {
            var components = Calendar.current.dateComponents([.year, .month], from: self.selectedMonth)
            components.month = (components.month ?? 0) + 1
            let endOfMonth = Calendar.current.date(from: components)!
            return endOfMonth
        }
    }

struct DateView: View {
// other code
}

我可以在其他视图中访问 startDateOfMonth 和 endDateOfMonth,如下所示:

Text("\(self.selectedDate.startDateOfMonth)")

但是当我尝试在我的TransactionsListView的 fetchRequest 初始化程序中使用 ObservableObject 中的这些变量时,我遇到了一个问题:

    import SwiftUI
    
    struct TransactionsListView: View {
    
    @Environment(\.managedObjectContext) var managedObjectContext
        var fetchRequest: FetchRequest<NPTransaction>
        var transactions: FetchedResults<NPTransaction> { fetchRequest.wrappedValue }
    @EnvironmentObject var selectedDate: SelectedDate

    // other code
            init() {
                    fetchRequest = FetchRequest<NPTransaction>(entity: NPTransaction.entity(), sortDescriptors: [
                        NSSortDescriptor(keyPath: \NPTransaction.date, ascending: false)
                    ], predicate: NSPredicate(format: "date >= %@ AND date < %@", self.selectedDate.startDateOfMonth as NSDate, self.selectedDate.endDateOfMonth as NSDate))
            }
    
    var body: some View {
    // other code
    }
    }

我收到一个错误:

在初始化之前使用的变量“self.fetchRequest”

我做错了什么?我试图在没有 self 的情况下在 init 中使用这些变量。同样的错误。它起作用的唯一方法是,如果这些 startDateOfMonth 和 endDateOfMonth 不在 ObservableObject 中,而是作为祖先视图中的一个变量,我通过 fetchRequest init 作为参数传递给我的视图。但是我很少有这样的视图,并且想使用 ObservableObject,而不是一直将相同的参数传递给子视图。

4

3 回答 3

1

问题是你不能@EnvironmentObjectinit(). 此处可能的选项是将EnvironmentObjectas 参数传递给视图。然后在 init 中使用该参数。这是视图的构造函数,然后您可以使用局部变量访问 start 和 endTime selectedDate

init(selectedDate : SelectedDate) 
{
   //now you can access selectedDate here and use it in FetchRequest
   fetchRequest = FetchRequest<NPTransaction>(entity: NPTransaction.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \NPTransaction.date, ascending: false)], predicate: NSPredicate(format: "date >= %@ AND date < %@", selectedDate.startDateOfMonth as NSDate, selectedDate.endDateOfMonth as NSDate))
}

在调用该视图的地方,传递EnvironmentObjectas 参数。

                                    //Declared as Environment Object
TransactionsListView(selectedDate : self.selectedDate)
于 2020-07-06T09:32:30.693 回答
0

您可以将其作为参数传递给视图:

import SwiftUI

struct TransactionsListView: View {

    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest var transactions: FetchedResults<NPTransaction>

    init(selectedDate: SelectedDate) {
        _transactions = FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \NPTransaction.date, ascending: false)], predicate: NSPredicate(format: "date >= %@ AND date < %@", selectedDate.startDateOfMonth as NSDate, selectedDate.endDateOfMonth as NSDate))
    }

    var body: some View {
    // other code
    }
}

selectedDateas存储@State在 superview 中并TransactionsListView使用当前值重新创建。

于 2020-09-01T05:59:47.850 回答
0

Swift 保证所有属性都在 init 之后初始化。

访问对象属性时,假设对象已经初始化,而在初始化过程中访问它时并非如此。

发生的情况是,当您初始化 时fetchRequest,您访问self.selectedDate(无论是否添加 self 对编译器都相同),这表明 self 已初始化,这意味着fetchRequest作为 self 的属性之一,可以使用。因此编译器错误:

在初始化之前使用的变量“self.fetchRequest”

使fetchRequest计算或惰性属性应该工作。(不太熟悉@FetchRequest

希望这可以帮助。

于 2020-07-06T06:55:16.077 回答