Grouping CoreData by Date() in SwiftUI List as sections(按日期()将SWIFTUI列表中的CoreData分组为节)
问题描述
我的目标:
我希望能够按CoreData待办事项的过期范围对其进行分组。(今天&q;、明天&q;、未来7天&q;)
我尝试的内容.
我尝试使用@SectionedFetchRequest,但sectionIdentifier需要字符串。如果它作为日期()存储在CoreData中,我如何转换它以供使用呢?我收到了许多错误和建议,但都无济于事。这也不适用于日期范围,如&Quot;NEXT 7 DATE&QOOT;。此外,我似乎甚至没有访问实体的duedate,因为它指向我的ViewModel表单。
@Environment(.managedObjectContext) private var viewContext
//Old way of fetching Todos without the section fetch
//@FetchRequest(sortDescriptors: []) var todos: FetchedResults<Todo>
@SectionedFetchRequest<String, Todo>(
entity: Todo.entity(), sectionIdentifier: Todo.dueDate,
SortDescriptors: [SortDescriptor(.Todo.dueDate, order: .forward)]
) var todos: SectionedFetchResults<String, Todo>
Cannot convert value of type 'KeyPath<Todo, Date?>' to expected argument type 'KeyPath<Todo, String>'
Value of type 'NSObject' has no member 'Todo'
询问
有没有比@SectionedFetchRequest?更适合我的情况的解决方案。如果没有,我希望看到如何对数据进行适当分组。
推荐答案
您可以在entityextension中制作您自己的sectionIdentifier,@SectionedFetchRequest
返回变量只需返回您的范围共有的内容,它才能正常工作。
extension Todo{
///Return the string representation of the relative date for the supported range (year, month, and day)
///The ranges include today, tomorrow, overdue, within 7 days, and future
@objc
var dueDateRelative: String{
var result = ""
if self.dueDate != nil{
//Order matters here so you can avoid overlapping
if Calendar.current.isDateInToday(self.dueDate!){
result = "today"//You can localize here if you support it
}else if Calendar.current.isDateInTomorrow(self.dueDate!){
result = "tomorrow"//You can localize here if you support it
}else if Calendar.current.dateComponents([.day], from: Date(), to: self.dueDate!).day ?? 8 <= 0{
result = "overdue"//You can localize here if you support it
}else if Calendar.current.dateComponents([.day], from: Date(), to: self.dueDate!).day ?? 8 <= 7{
result = "within 7 days"//You can localize here if you support it
}else{
result = "future"//You can localize here if you support it
}
}else{
result = "unknown"//You can localize here if you support it
}
return result
}
}
然后将其与您的@SectionedFetchRequest一起使用,如下所示
@SectionedFetchRequest(entity: Todo.entity(), sectionIdentifier: .dueDateRelative, sortDescriptors: [NSSortDescriptor(keyPath: Todo.dueDate, ascending: true)], predicate: nil, animation: Animation.linear)
var sections: SectionedFetchResults<String, Todo>
也查看this question
您也可以使用Date,但您必须选择一个日期作为节标题。在此方案中,您可以使用范围的上行日期,只使用日期而不是时间,因为如果它们不匹配,时间可能会创建其他部分。
extension Todo{
///Return the upperboud date of the available range (year, month, and day)
///The ranges include today, tomorrow, overdue, within 7 days, and future
@objc
var upperBoundDueDate: Date{
//The return value has to be identical for the sections to match
//So instead of returning the available date you return a date with only year, month and day
//We will comprare the result to today's components
let todayComp = Calendar.current.dateComponents([.year,.month,.day], from: Date())
var today = Calendar.current.date(from: todayComp) ?? Date()
if self.dueDate != nil{
//Use the methods available in calendar to identify the ranges
//Today
if Calendar.current.isDateInToday(self.dueDate!){
//The result variable is already setup to today
//result = result
}else if Calendar.current.isDateInTomorrow(self.dueDate!){
//Add one day to today
today = Calendar.current.date(byAdding: .day, value: 1, to: today)!
}else if Calendar.current.dateComponents([.day], from: today, to: self.dueDate!).day ?? 8 <= 0{
//Reduce one day to today to return yesterday
today = Calendar.current.date(byAdding: .day, value: -1, to: today)!
}else if Calendar.current.dateComponents([.day], from: today, to: self.dueDate!).day ?? 8 <= 7{
//Return the date in 7 days
today = Calendar.current.date(byAdding: .day, value: 7, to: today)!
}else{
today = Date.distantFuture
}
}else{
//This is something that needs to be handled. What do you want as the default if the date is nil
today = Date.distantPast
}
return today
}
}
然后请求将如下所示.
@SectionedFetchRequest(entity: Todo.entity(), sectionIdentifier: .upperBoundDueDate, sortDescriptors: [NSSortDescriptor(keyPath: Todo.dueDate, ascending: true)], predicate: nil, animation: Animation.linear)
var sections: SectionedFetchResults<Date, Todo>
根据您提供的信息,您可以测试此代码,方法是将我提供的扩展粘贴到项目的.swift文件中,并将获取请求替换为您要使用的请求
这篇关于按日期()将SWIFTUI列表中的CoreData分组为节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:按日期()将SWIFTUI列表中的CoreData分组为节
基础教程推荐
- iPhone - 获取给定地点/时区的当前日期和时间并将其与同一地点的另一个日期/时间进行比较的正确方法 2022-01-01
- AdMob 广告未在模拟器中显示 2022-01-01
- libGDX 从精灵或纹理中获取像素颜色 2022-01-01
- navigator.geolocation.getCurrentPosition 在 Android 浏览器上 2022-01-01
- 通过重定向链接在 Google Play 中打开应用 2022-01-01
- Cocos2d iPhone 非矩形精灵触摸检测 2022-01-01
- NSString intValue 不能用于检索电话号码 2022-01-01
- iOS4 创建后台定时器 2022-01-01
- Android:getLastKnownLocation(LocationManager.NETWORK_PROVIDER 2022-01-01
- 如何从 logcat 中删除旧数据? 2022-01-01
