简体   繁体   English

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

[英]How can I dynamically work with FetchRequest data in SwiftUI view

I am trying to create a calorie counter view using SwiftUI where workout data is fetched from Core Data and besides writing all of the data out I want to get total number of burnt calories for today.我正在尝试使用 SwiftUI 创建一个卡路里计数器视图,其中锻炼数据是从核心数据中获取的,除了写出所有数据之外,我还想获得今天燃烧的卡路里总数。 I was thinking of going through the fetched data, check whether its createdAt attribute equals current Date() and if so add it up to sum of self.totalCaloriesBurntToday .我正在考虑查看获取的数据,检查其createdAt属性是否等于当前Date() ,如果是,则将其加到self.totalCaloriesBurntToday的总和中。

I got an error that ForEach of this type does not conform to certain protocols:我收到一个错误,表明这种类型的 ForEach 不符合某些协议:

Type '()' cannot conform to 'View';类型 '()' 不能符合 'View'; only struct/enum/class types can conform to protocols只有结构/枚举/类类型可以符合协议

Here is my code:这是我的代码:

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)")
    }
}

I want to output the sum later and want it to change dynamically.我想稍后将总和 output 并希望它动态更改。 Everytime some data object is added or deleted the sum would automatically adjust.每次添加或删除一些数据 object 时,总和会自动调整。

I have tried to go around this using UserDefaults to save the calories there, but there is the problem that the change of data in UserDefaults does not automatically push for changes in the view and hence it is not dynamic.我曾尝试使用 UserDefaults 围绕此 go 来保存卡路里,但存在的问题是 UserDefaults 中的数据更改不会自动推动视图中的更改,因此它不是动态的。

The SwiftUI's ForEach you used has a return type of Content , which means for every item in the loop it has to return some View .您使用的 SwiftUI 的ForEach有一个返回类型Content ,这意味着对于循环中的每个项目,它都必须返回一些View It's not the same as a simple foreach loop.它与简单的foreach循环不同。

You can use reduce to calculate totalCaloriesBurnt and filter to choose only today's workouts.您可以使用reduce来计算totalCaloriesBurntfilter以仅选择今天的锻炼。

For comparing dates it's better to use Calendar.compare :为了比较日期,最好使用Calendar.compare

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

Summing up your code can look like this:总结您的代码可能如下所示:

workoutData
  .filter { Calendar.current.compare($0.createdAt, to: Date(), toGranularity: .day) == .orderedSame }
  .reduce(0) { $0 + Int($1.caloriesBurnt)! }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM