在SwiftUI中,什么';当基础数据未更改时,基于基础数据动态更新行的最佳方法是什么?
我有一个从核心数据中列出在SwiftUI中,什么';当基础数据未更改时,基于基础数据动态更新行的最佳方法是什么?,swiftui,Swiftui,我有一个从核心数据中列出事件的应用程序。每个事件都有一个日期 当我列出事件时,我想显示日期,除非日期是今天或昨天,在这种情况下,我想显示今天或昨天而不是日期 到目前为止,我有一个函数处理生成要在行中显示的字符串。然而,我注意到,如果一天过去了,我重新打开应用程序,它会显示过时的信息。例如,如果前一天有一个事件说我前一天打开应用程序时是今天,那么当我重新打开应用程序时,它仍然会说今天而不是昨天。很明显,这个函数并不是每次我打开应用程序时都会被调用,但我想知道让它更具动态性的最佳方法是什么 这些是我
事件的应用程序。每个事件都有一个日期
当我列出事件时,我想显示日期
,除非日期
是今天或昨天,在这种情况下,我想显示今天或昨天而不是日期
到目前为止,我有一个函数处理生成要在行中显示的字符串。然而,我注意到,如果一天过去了,我重新打开应用程序,它会显示过时的信息。例如,如果前一天有一个事件说我前一天打开应用程序时是今天,那么当我重新打开应用程序时,它仍然会说今天而不是昨天。很明显,这个函数并不是每次我打开应用程序时都会被调用,但我想知道让它更具动态性的最佳方法是什么
这些是我正在考虑的途径,但不确定什么是最好的,所以我想在这里发布建议,看看我是否忽略了任何重要的东西:
- 每次打开应用程序时,用行上的
.onAppear
重新计算它(我不确定每个事件的日期计算费用有多高,但即使不贵,我也不确定当应用程序出现在前台时,我如何告诉行重新运行函数)
- 切换到一个计算属性(我不知道这是否会与我现在所做的那样将一个函数放入其中有所不同。如果每次调用都很昂贵,那么每次调用它可能会很糟糕,但假设不是这样,那么每次应用程序出现在前台时,我如何让它刷新?)
- 提出一个解决方案,在日期发生变化时只重新计算每一行(如果我知道行计算非常昂贵,我可能会尝试这样做,但在这里似乎有点过分,而且我也不确定如何告诉每一行重新运行函数)
这是我的代码(我省略了日期格式化程序代码,但这是相当标准的,对此不重要):
struct ContentView:View{
@FetchRequest(FetchRequest:Event.EventsWestFirst)
私有var事件:FetchedResults
var body:一些观点{
导航视图{
ForEach(events){event in
EventRow(事件:事件)
}
}
}
}
结构EventRow:视图{
@ObservedObject变量事件:事件
var body:一些观点{
文本(event.dateAndTimeString())
}
}
扩展事件{
func dateAndTimeString()->String{
guard let date=self.date else{return“Error”}
让timeString=DateAndNumberFormatters.simpleTimeDisplay.string(from:date)
让dateString:String
如果让todayOrYesterday=date.asTodayOrYesterday(){
dateString=今天或昨天
}否则{
dateString=DateAndNumberFormatters.simpleShortDateDisplay.string(从:日期)
}
在\(时间字符串)处返回“\(日期字符串)”
}
}
延期日期{
func asTodayOrYesterday()->字符串{
让calendar=calendar.current
let dayComponents=calendar.dateComponents([.year、.month、.day],from:self)
让todayDateComponents=calendar.dateComponents([.year、.month、.day],from:Date())
var yesterdayDateComponents=calendar.dateComponents([.year、.month、.day],from:Date())
yesterdayDateComponents.day=yesterdayDateComponents.day!-1
let dayDate:Date!=日历.日期(从:dayComponents)
让todayDayDate:Date!=日历.Date(从:todayDateComponents)
让yesterdayDayDate:Date!=日历.Date(从:yesterdayDateComponents)
开关日期{
今日个案日期:
返回“今天”
案件昨天日期:
返回“昨天”
违约:
归零
}
}
}
可能的方法是观察场景阶段,并根据需要强制刷新观察到的核心数据对象,如
struct EventRow: View {
@ObservedObject var event: Event
@Environment(\.scenePhase) var scenePhase
var body: some View {
Text(event.dateAndTimeString())
.onChange(of: scenePhase) {
if $0 == .active {
event.objectWillChange.send()
}
}
}
}
struct EventRow: View {
@ObservedObject var event: Event
@Environment(\.scenePhase) var scenePhase
var body: some View {
Text(event.dateAndTimeString())
.onChange(of: scenePhase) {
if $0 == .active {
event.objectWillChange.send()
}
}
}
}