Greg
Greg

Reputation: 34818

how to remove delete button in SwiftUI List rows when in Edit Mode?

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...

Upvotes: 5

Views: 5503

Answers (2)

Asperi
Asperi

Reputation: 258057

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!)
    }
}

Upvotes: 1

LuLuGaGa
LuLuGaGa

Reputation: 14388

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

Upvotes: 7

Related Questions