Core Data数据分组展示的SectionedFetchRequest
Core Data数据分组展示的SectionedFetchRequest

Core Data数据分组展示的SectionedFetchRequest

SectionedFetchRequest 是 SwiftUI 中用来将 Core Data 的数据按某个属性分组展示的机制,常用于 List 的分组展示,比如想按“日期”、“类别”、“国家”等属性把数据分区。

基本语法

@SectionedFetchRequest(
    sectionIdentifier: \Entity.sectionAttribute,
    sortDescriptors: [SortDescriptor(\Entity.sectionAttribute), SortDescriptor(\Entity.name)]
) private var items: SectionedFetchResults<String, Entity>

sectionIdentifier: 用哪个属性来分组。

sortDescriptors: 排序规则,通常要包括分组字段和列表内排序字段。

SectionedFetchResults<SectionIdentifier, Entity>: Section 的类型(比如 String, Date),和实体类型。

代码示例

按日期分组的外币购买记录

假设有一个实体叫 CurrencyRecord,属性如下:

1、currency: String

2、amount: Double

3、buyDate: Date

想按日期分组:

@SectionedFetchRequest(
    sectionIdentifier: \CurrencyRecord.buyDate,
    sortDescriptors: [
        SortDescriptor(\CurrencyRecord.buyDate, order: .reverse),
        SortDescriptor(\CurrencyRecord.currency)
    ],
    animation: .default
)
private var records: SectionedFetchResults<Date, CurrencyRecord>

然后在 View 中使用:

List {
    ForEach(records) { section in
        Section(header: Text(section.id.formatted(date: .abbreviated, time: .omitted))) {
            ForEach(section) { record in
                HStack {
                    Text(record.currency)
                    Spacer()
                    Text("\(record.amount, specifier: "%.2f")")
                }
            }
        }
    }
}

注意事项

1、sectionIdentifier 的属性必须是 Hashable。

2、如果是 Date 类型,考虑按“日”分组(忽略时分秒),否则每条记录都是一个 Section,可以通过扩展 Date 做标准化:

extension Date {
    var startOfDay: Date {
        Calendar.current.startOfDay(for: self)
    }
}

然后建一个 transient 属性 buyDay 映射为 startOfDay。

3、SectionedFetchRequest 仅适用于 iOS 15+。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注