SwiftUI Swipe to delete on list action very hard to trigger

Viewed 544

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)
                
0 Answers
Related