如何在SwiftUi视图中动态处理FetchRequest数据

问题描述 投票:0回答:1

[我正在尝试使用SwiftUI创建卡路里计数器视图,在该视图中,锻炼数据是从Core Data中获取的,除了将所有数据写出之外,我还想获得今天消耗的卡路里总数。我正在考虑遍历提取的数据,检查其createdAt属性是否等于当前Date(),如果是,则将其加到self.totalCaloriesBurntToday的总和。

我收到此类型的ForEach不符合某些协议的错误:

类型'()'不符合'视图';只有struct / enum / class类型可以符合协议]

这是我的代码:

import SwiftUI

struct ProgressBar: View {
    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(
        entity: WorkoutInputData.entity(),
        sortDescriptors: []
    ) var workoutData: FetchedResults<WorkoutInputData>

    @State private var totalCaloriesBurntToday : Int


    var body: some View {
        ForEach(workoutData) { singleWorkout in
            if singleWorkout.createdAt == Date(){
                self.totalCaloriesBurntToday += Int(singleWorkout.caloriesBurnt)!
            }
        }
        return Text("\(self.totalCaloriesBurntToday)")
    }
}

我想稍后输出总和并希望其动态变化。每次添加或删除某些数据对象时,总和将自动调整。

我已经尝试使用UserDefaults来解决此问题以在其中保存卡路里,但是存在UserDefaults中数据的更改不会自动推送视图中的更改,因此它不是动态的问题。

swift xcode foreach nsfetchrequest
1个回答
0
投票

您使用的SwiftUI的ForEach的返回类型为Content,这意味着循环中的每个项目都必须返回一些View。它与简单的foreach循环不同。

您可以使用reduce计算totalCaloriesBurnt,并且filter仅选择今天的锻炼。

为了比较日期,最好使用Calendar.compare

Calendar.current.compare(singleWorkout.createdAt, to: Date(), toGranularity: .day) == .orderedSame

总结您的代码如下所示:

workoutData
  .filter { Calendar.current.compare($0.createdAt, to: Date(), toGranularity: .day) == .orderedSame }
  .reduce(0) { $0 + Int($1.caloriesBurnt)! }
© www.soinside.com 2019 - 2024. All rights reserved.