#ios #swift #swiftui #swiftui-list #nsindexset
#iOS #swift #swiftui #swiftui-список #nsindexset
Вопрос:
Я пытаюсь использовать .delete
метод SwiftUI в списке, чтобы определить, что 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]
}
Ответ №1:
Вы IndexSet
передали в качестве параметра. Это можно использовать для удаления правильных тренировок
workoutMonths.remove(atOffsets: offsets)
Если вы хотите собрать все объекты, которые должны быть удалены, вы также можете выполнить итерацию, используя цикл foreach . Затем вы получаете доступ к каждому из объектов, которые будут удалены.
for offset in offsets {
var workoutMonth: WorkoutMonth = workoutMonths[offset]
}
Комментарии:
1. Я не могу просто использовать
.remove(atOffsets)
, потому что мне нужно позвонить. удаление при тренировке в API HealthKit от Apple. И я не могу использовать 2-й пример, потому что я не знаю, сколько существует смещений.2. @GarySabo зачем вам нужно знать точное количество? разве недостаточно только для каждого? На нем также доступно количество. Я не совсем понимаю проблему. Если вам нужны точные объекты тренировки — лучше всего использовать для каждого цикла, создайте массив этих удаленных объектов, а затем удалите их из HealthKit API как коллекцию объектов
3. Мне нужен доступ к тренировке. Проблема в том, что у меня есть доступ к тренировке в
ForEach(workoutMonth.trackerWorkouts) { workout in
правильном, но my .delete находится за пределами этого цикла, поэтому у меня нет его для передачиHKHealthStore.delete(workout)
Ответ №2:
Я понял это, у меня был свой .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)")
}
}