如何使用 IndexSet 在自定义结构中查找项目
How to use IndexSet to find item in a custom Struct
我正在尝试在列表中使用 SwiftUI 的 .delete
方法来识别 HKWorkout
用户试图删除的内容,但由于我将我的锻炼打包到自定义 WorkoutMonth 对象中,所以我'我很难弄清楚如何深入了解用户正在点击的特定锻炼?在 UIKIT 中,我能够使用 indexPath.section
和 indexPath.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)")
}
}
我正在尝试在列表中使用 SwiftUI 的 .delete
方法来识别 HKWorkout
用户试图删除的内容,但由于我将我的锻炼打包到自定义 WorkoutMonth 对象中,所以我'我很难弄清楚如何深入了解用户正在点击的特定锻炼?在 UIKIT 中,我能够使用 indexPath.section
和 indexPath.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)")
}
}