如何使用 IndexSet 在自定义结构中查找项目

How to use IndexSet to find item in a custom Struct

我正在尝试在列表中使用 SwiftUI 的 .delete 方法来识别 HKWorkout 用户试图删除的内容,但由于我将我的锻炼打包到自定义 WorkoutMonth 对象中,所以我'我很难弄清楚如何深入了解用户正在点击的特定锻炼?在 UIKIT 中,我能够使用 indexPath.sectionindexPath.row 找到它,但在这里我迷路了。

struct MonthsWorkoutsListView: View {
    
    
    @Environment(\.colorScheme) var colorScheme
    @EnvironmentObject var trackerDataStore: TrackerDataStore
    @State var workouts: [TrackerWorkout]
    @State var workoutMonths = [WorkoutMonth]()
    
    var body: some View {
        VStack {
            if workoutMonths.count == 0 {
                Text("No workouts logged yet.  Open the Athlytic App on your Apple Watch to start and save a new workout.")
                    .multilineTextAlignment(.center)
                    .padding(.horizontal)
            } else {
                List {
                    ForEach(workoutMonths) { workoutMonth in
                        Section(header: Text(getFormattedYearMonth(workoutMonth: workoutMonth))) {
                            ForEach(workoutMonth.trackerWorkouts) { workout in
                                NavigationButton(
                                    action: {
                                        trackerDataStore.selectedWorkout = workout //this line is needed so that the image  at the top of WorkoutDetailHeaderCard gets updated,  otherwise the view loads before the async called and you end up with the  image of the last selected workout
                                        trackerDataStore.loadDataForSelectedWorkout(selectedWorkoutToBeUpdated: workout)
                                    },
                                    destination: {
                                        WorkoutDetailView().environmentObject(trackerDataStore)
                                    },
                                    workoutRow: { WorkoutRow(trackerWorkout: workout) }
                                )
                            }
                        }
                    }
                    .onDelete(perform: delete)
                }
                .navigationBarTitle(Text("Workouts"))
            }
        }
        .onAppear {
            workoutMonths = buildWorkoutsIntoYearMonths(workouts: workouts)
        }
    }
    
    func delete(at offsets: IndexSet) {

        //How to look up the workout user wants to delete?

    }

struct YearMonth: Comparable, Hashable {
    
    let year: Int
    let month: Int
    
    init(year: Int, month: Int) {
        self.year = year
        self.month = month
    }
    
    init(date: Date) {
        let comps = Calendar.current.dateComponents([.year, .month], from: date)
        self.year = comps.year!
        self.month = comps.month!
    }
    
    static func < (lhs: YearMonth, rhs: YearMonth) -> Bool {
        if lhs.year != rhs.year {
            return lhs.year < rhs.year
        } else {
            return lhs.month < rhs.month
        }
    }
}

struct WorkoutMonth: Identifiable {
    var id = UUID()
    var yearMonth: YearMonth
    var trackerWorkouts: [TrackerWorkout]
}

您已将 IndexSet 作为参数传递。这个可以用来删除适当的锻炼

workoutMonths.remove(atOffsets: offsets)

如果您想收集所有应该删除的对象,您也可以使用foreach 循环进行迭代。然后您可以访问每个将被删除的对象。

for offset in offsets {
   var workoutMonth: WorkoutMonth = workoutMonths[offset]
}

我想出来了,我把我的 .delete 放在外面 forEach 下,把它放在这里让我可以访问 workoutMonth

ForEach(workoutMonth.trackerWorkouts) { workout in
    NavigationButton(
        action: {
            trackerDataStore.selectedWorkout = workout
            trackerDataStore.loadDataForSelectedWorkout(selectedWorkoutToBeUpdated: workout)
        },
        destination: {
            WorkoutDetailView().environmentObject(trackerDataStore)
        },
        workoutRow: { WorkoutRow(trackerWorkout: workout) }
    )
}
.onDelete { (offSets) in
    for offset in offSets {
    print("user wants to delete workout \(workoutMonth.trackerWorkouts[offset].startDate)")
    }
}