3
votes

How would remove the delete button in SwiftUI List rows when in Edit Mode? Note the hamburger button on the right of the row that allows rows to be re-ordered needs to continue to function.

Background - Want a list that has the "re-order" rows functions always enabled. Edit mode seems to enable this (i.e. leave List in edit mode) however do not want the red delete button on each row.

This is a SwiftUI specific question.

EDIT: After removing the delete button only here, so the swipe to delete still works...

2
Hi @Greg, did you find solution for your question ? - Karen Karapetyan
No. So I've just assumed it's not possible for the moment - Greg
Hi @Greg, seems this guy found the way, stackoverflow.com/a/58770635/5903004 - Karen Karapetyan

2 Answers

6
votes

There is a modifier for that, just add '.deleteDisabled(true)'. You can also pass a variable into it making the delete disabled conditionally.

1
votes

Xcode 11.2, Swift 5.1 Just don't provide onDelete in List and there will be no Delete buttons

Here is example

no delete button

import SwiftUI
import Combine

struct ContentView: View {
    @State private var objects = ["1", "2", "3"]

    var body: some View {
        NavigationView {
            List {
                ForEach(objects, id: \.self) { object in
                    Text("Row \(object)")
                }
                .onMove(perform: relocate)
            }
            .navigationBarItems(trailing: EditButton())
        }
    }

    func relocate(from source: IndexSet, to destination: Int) {
        objects.move(fromOffsets: source, toOffset: destination)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Alternate approach (with limitations)

struct ContentView: View {
    @State private var objects = ["1", "2", "3"]
    @Environment(\.editMode) var editMode

    var body: some View {
//        NavigationView {
        VStack {
            // !!!  A. using NavigationView instead of VStack above does not work,
            // !!!  because editMode is not updated and always .inactive
            // !!!  B. Also it does not work in Preview, but works in run-time
            EditButton()
            List {

                ForEach(objects, id: \.self) { object in
                    Text("Row \(object)")
                }
                .onMove(perform: relocate)
                .onDelete(perform: delete)
                .deleteDisabled(disableDelete)
            }
//                .navigationBarItems(trailing: EditButton())
        }
    }

    var disableDelete: Bool {
        if let mode = editMode?.wrappedValue, mode == .active {
            return true
        }
        return false
    }

    func relocate(from source: IndexSet, to destination: Int) {
        objects.move(fromOffsets: source, toOffset: destination)
    }

    func delete(from source: IndexSet?) {
        objects.remove(atOffsets: source!)
    }
}