Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programmatically make a List's editMode inactive when leaving the view with SwiftUI?

Tags:

swift

swiftui

Given a List view with an EditButton() in there, if the view is being edited (user tapped the Edit button), how can one disable the edit mode programmatically when the user navigates away from the view? (e.g. similar behavior to the Favorites view in the Phone app on the iPhone)

struct ContentView2: View {
    @State var fruits = ["Apple", "Banana"]

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onDelete { _ in
                    print("Delete")
                }
            }
            .toolbar {
                EditButton()
            }
        }
        .onDisappear {
            // make List's editMode be .inactive; how?
        }
    }
}
like image 227
vmallet Avatar asked Oct 30 '25 18:10

vmallet


1 Answers

You can use .environment to bind the List's current edit mode with a @State property, as shown in this awesome article.

struct ContentView: View {
    @State var editMode = EditMode.inactive /// the edit mode

    @State var fruits = ["Apple", "Banana"]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onDelete { _ in
                    print("Delete")
                }
            }
            .toolbar {
                EditButton()
            }
            .environment(\.editMode, $editMode) /// bind it here!
        }
        .onDisappear {
            editMode = .inactive /// set to inactive
        }
    }
}

Also, your onDisappear won't be called if you're using a NavigationLink to present a new view, because the NavigationView that you attached it to won't actually disappear. You should attach it to the NavigationLink's label instead (from this answer).

Final code:

struct ContentView: View {
    @State var editMode = EditMode.inactive /// the edit mode
    @State var fruits = ["Apple", "Banana"]
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination:  Text("New view!")) {
                    Text("Navigate away")
                        .onDisappear {
                            editMode = .inactive /// set to inactive
                        }
                }
                
                List {
                    ForEach(fruits, id: \.self) { fruit in
                        Text(fruit)
                    }
                    .onDelete { _ in
                        print("Delete")
                    }
                }
                .toolbar {
                    EditButton()
                }
                .environment(\.editMode, $editMode) /// bind it here!
            }
        }
    }
}

Result:

Without editMode = .inactive With editMode = .inactive
List stays in edit mode after presenting new view and coming back List exits edit mode after presenting new view and coming back
like image 97
aheze Avatar answered Nov 02 '25 10:11

aheze