You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让SwiftUI的NavigationLink仅展示当日摄入的食物条目?

问题:如何让卡路里追踪应用仅展示当日摄入的食物列表?

我正在为一款简易卡路里追踪应用添加功能,该应用用于统计全天摄入的卡路里。当前负责展示已摄入食物列表的代码如下:

List {
    ForEach(food) { food in
        NavigationLink(destination: EditFoodView(food: food)) {
            HStack {
                VStack(alignment: .leading, spacing: 6) {
                    Text(food.name!)
                        .bold()

                    Text("\(Int(food.calories))") + Text(" calories").foregroundColor(.red)
                }
                Spacer()
                Text(calcTimeSince(date: food.date!))
                    .foregroundColor(.gray)
                    .italic()
            }
        }
    }
    .onDelete(perform: deleteFood)
}
.listStyle(.plain)

如您所见,该列表会展示CoreData数据库中存储的所有食物。请问是否有办法让该列表仅展示当日摄入的食物?


解决方案

有两种可行的实现方式,可根据你的数据规模和获取方式选择:

1. 过滤已加载的食物数组

如果你的food是已经从CoreData获取到的内存数组,可以直接在ForEach中添加过滤逻辑,只保留当日记录。

先添加一个判断日期是否为当天的辅助函数:

func isToday(_ date: Date) -> Bool {
    let calendar = Calendar.current
    return calendar.isDateInToday(date)
}

然后修改ForEach的数据源:

ForEach(food.filter { isToday($0.date!) }) { food in
    // 原列表项代码保持不变
}

这种方式简单直接,适合数据量较小的场景。

2. 直接从CoreData查询当日数据(推荐)

如果应用中食物数据量较大,过滤内存数组会浪费性能,更高效的方式是在查询CoreData时就限定只获取当日记录。

使用NSPredicate设置日期范围条件:

let calendar = Calendar.current
let startOfDay = calendar.startOfDay(for: Date())
// 计算当日结束时间(次日0点)
let endOfDay = calendar.date(byAdding: .day, value: 1, to: startOfDay)!

// 创建查询条件:date >= 当日0点 且 date < 次日0点
let predicate = NSPredicate(format: "date >= %@ AND date < %@", startOfDay as CVarArg, endOfDay as CVarArg)

// 将predicate应用到CoreData的获取请求中
let fetchRequest: NSFetchRequest<Food> = Food.fetchRequest()
fetchRequest.predicate = predicate
// 执行请求获取当日数据

通过这种方式获取的food数组本身就只包含当日记录,直接传入列表即可,无需额外过滤,性能更优。


内容的提问来源于stack exchange,提问作者Ralph L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:54:28