I have a list with a ForEach that has the .ondelete function however it is very difficult to get the swipe action to work correctly (1 in 100 swipes work) and display the delete button. Once it does it all works correctly and the delete works.
struct ActivitySelectorView: View {
varibles here
var body: some View {
ZStack {
//backgroundColor
Color("\(activityToSave.category)Color")
VStack {
//Title Bar
TitleBar(showingAlert: $showingAlert, showActivitySelector: $showActivitySelector, categoryName: categoryNames[(Int(String(activityToSave.category.last!)) ?? 1) - 1])
List {
SearchBar(text: $searchText)
ForEach(fetchRequest.wrappedValue.filter({ searchText.isEmpty ? true : $0.name.contains(searchText) }), id: \.self) { activity in
HStack {
Text(activity.name.capitalized)
Spacer()
}
.frame(height: 30)
.contentShape(Rectangle())
.onTapGesture {
self.showActivitySelector = false
self.activityToSave.activityName = activity.name.capitalized
}
}
.onDelete(perform: deleteActivity)
}
.resignKeyboardOnDragGesture()
}
TextFieldAlert(isShowing: $showingAlert, text: $alertInput, category: activityToSave.category)
.offset(x: 60, y: self.showingAlert ? -100 : screen.height)
}
}
func deleteActivity(at offsets: IndexSet) {
for index in offsets {
let activity = fetchRequest.wrappedValue[index]
viewContext.delete(activity)
}
do {
try viewContext.save()
} catch {
print(error)
}
}
Edit for more context
In ContentView I have a button which changes the offset of a view called AddActivityView seen here.
//MARK: - Add activity view
AddActivityView(
showActivitySelector: $showActivitySelector,
activityToSave: activityToSave,
showAddActivity: $showAddActivity,
isEditScreen: false,
selectedDate: $daySelected,
itemToDelete: $activityToDelete,
showingNameEditor: $showCategoryNameEditor,
category1Name: $category1Name,
category2Name: $category2Name,
category3Name: $category3Name,
category4Name: $category4Name
)
.clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous))
.frame(width: screen.width, height: screen.height - 60, alignment: .leading)
.offset(y: activityViewState.height)
.offset(x: 0, y: showAddActivity ? 60 : screen.height)
.animation(.easeInOut)
.gesture(
DragGesture()
.onChanged{ value in
if self.activityViewState.height > -1 {
self.activityViewState = value.translation
}
}
.onEnded{ value in
if self.activityViewState.height > 100 {
self.showAddActivity = false
self.showActivitySelector = false
self.showCategoryNameEditor = false
resetActivity(activityToSave)
}
self.activityViewState = .zero
}
)
Then in that view there is a button which change offset of another view called ActivitySelectorView which is the view at the top which contains the list
//MARK: - ActivitySelectorView
ActivitySelectorView(filter: activityToSave.category, showActivitySelector: $showActivitySelector, activityToSave: activityToSave, allActivities: activities, categoryNames: categoryNames)
.environmentObject(activityToSave)
.frame(width: screen.width, height: screen.height)
.offset(x: showActivitySelector ? 0 : screen.width)
.offset(y: screen.minY)
.offset(x: viewState.width)
.animation(.easeInOut)