SwiftUI中CoreData获取特定年份收支数据的谓词编写方法
按特定年份过滤CoreData收支数据的谓词实现
首先要明确:CoreData的谓词无法直接使用计算属性进行过滤,因为计算属性不会被持久化到存储中。所以我们需要基于Expence实体中持久化的date属性来构建年份过滤的谓词,下面是两种可行的实现方式:
方式一:通过日期区间匹配年份
利用Calendar计算目标年份的起始和结束日期,生成包含全年的日期区间,再用谓词匹配date属性落在该区间内的数据:
// 假设要过滤的目标年份是2024 let targetYear = 2024 let calendar = Calendar.current // 构建当年1月1日0点的起始日期 guard let startDate = calendar.date(from: DateComponents(year: targetYear, month: 1, day: 1)) else { fatalError("无法生成起始日期") } // 构建下一年1月1日0点的结束日期(作为区间上限,确保包含全年所有时刻) guard let endDate = calendar.date(from: DateComponents(year: targetYear + 1, month: 1, day: 1)) else { fatalError("无法生成结束日期") } // 生成匹配日期区间的谓词 let predicate = NSPredicate(format: "date >= %@ AND date < %@", startDate as CVarArg, endDate as CVarArg)
方式二:直接提取日期的年份进行匹配
使用CoreData支持的表达式语法,直接从date属性中提取年份并与目标值匹配:
let targetYear = 2024 // 谓词格式:提取date的年份,等于目标年份 let predicate = NSPredicate(format: "date.year == %d", targetYear)
在@SectionedFetchRequest中应用谓词
如果年份固定,可直接在声明时传入谓词:
let targetYear = 2024 let predicate = NSPredicate(format: "date.year == %d", targetYear) @SectionedFetchRequest( sectionIdentifier: \Expence.itemMonthYearShort, sortDescriptors: [SortDescriptor(\Expence.date, order: .forward)], predicate: predicate ) private var expences: SectionedFetchResults<String, Expence>
如果需要动态切换年份,可结合@State变量生成动态请求:
@State private var selectedYear = 2024 private var filteredExpences: SectionedFetchResults<String, Expence> { let predicate = NSPredicate(format: "date.year == %d", selectedYear) return SectionedFetchRequest( sectionIdentifier: \Expence.itemMonthYearShort, sortDescriptors: [SortDescriptor(\Expence.date, order: .forward)], predicate: predicate ).wrappedValue }
注:方式一兼容性更好,适配更早的iOS/macOS版本;方式二更简洁直观,适合较新的系统版本。
内容的提问来源于stack exchange,提问作者RP89
相关产品推荐
相关产品推荐

