已更新
我正在使用EventKit从IOS日历中提取事件。效果很好。
这里是检索事件的类函数。
@ObservedObject var selectDate = datepicker() // does NOT update as expected.
func loadEvents(completion: @escaping (([EKEvent]?) -> Void)) {
requestAccess(onGranted: {
let startOfDay = Calendar.current.startOfDay(for: self.selectDate.selectedDate)
let endOfDay = Calendar.current.startOfDay(for: self.selectDate.selectedDate.advanced(by: TimeInterval.day))
let predicate = self.eventStore.predicateForEvents(withStart: startOfDay, end: endOfDay, calendars: Array(self.selectedCalendars ?? []))
let events = self.eventStore.events(matching: predicate)
completion(events)
print("loadEvents triggered for \(self.selectDate.selectedDate)") // This ALWAYS returns the current date
}) {
completion(nil)
}
}
我想根据所选日期更新结果。 所以我在主视图中将日期选择器分配给了@ObservedObject var selectDate
@ObservedObject var selectDate = datepicker()
DatePicker(
selection: $selectDate.selectedDate,
in: dateClosedRange,
displayedComponents: [.date, .hourAndMinute], label: { Text("Is hidden label") })
}
这个班子充当中间人。 didSet
方法正在触发该函数的运行,已通过上面loadEvents
函数中的print语句确认。
class datepicker: ObservableObject {
@Published var selectedDate: Date = Date() {
didSet {
print("class datepicker date changed to \(selectedDate)") // This returns the changed dates correctly
EventsRepository.shared.loadAndUpdateEvents()
}
}
}
我也尝试过这样传递新日期。
let startOfDay = Calendar.current.startOfDay(for: datepicker.init().selectedDate)
仅具有相同的持久“当前日期”。
每当更改datePicker中的 selectDate.selectedDate 时,如何将新的selectedDate传递给函数?
目前,它根本不更新。始终仅返回当天的事件。
上面的代码在Debug中返回的打印语句返回。
"class datepicker date changed to 2020-08-13 19:23:28 +0000" // YEP That's right. I used datePicker to select this date.
"loadEvents triggered for 2020-08-10 19:23:28 +0000" // NOT updated, ALWAYS shows current date/time as first run.
因此,看起来@Published属性是一个常量,一旦设置就无法更改。有其他选择吗?
答案 0 :(得分:2)
无论何时,如何重新触发func loadEvents 从datePicker中选择selectDate.selectedDate吗?
您可以尝试使用didSet
:
class datepicker: ObservableObject{
@Published var selectedDate: Date = Date() {
didSet {
// loadEvents()
}
}
}
在Xcode 11.6,iOS 13.6上进行了测试。
编辑
您似乎正在使用datepicker
对象的两个实例。确保在所有相关位置使用相同实例。
该对象只能创建一次:
@ObservedObject var selectDate = datepicker()
然后传递到init
中的其他位置。
答案 1 :(得分:1)
一种方法是在创建模型对象时实际订阅自己的发布者。
class DateManager: ObservableObject {
@Published var selectedDate: Date = .init()
private var bag: Set<AnyCancellable> = []
init() {
$selectedDate // $ prefix gets the projected value, a `Publisher` from `Published<>`
.receive(on: DispatchQueue.main)
.sink { [weak self] selectedDate in
self?.loadEvents(date: selectedDate)
}
.store(in: &bag)
}
}
这将订阅该发布者并在其更改时触发您的API调用。如果用户快速更改日期等,则可以花大钱并添加debounce
或稍加延迟。现在,您可以完全结合使用来控制此数据流。