我正在尝试使用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中的数据更改不会自动推送视图中的更改,因此它不是动态的。
答案 0 :(得分:1)
您使用的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)! }