How to Use a Button in navigationBarItems to Work with List

I have the following lines of code to work with a list of strings.

import SwiftUI

struct ContentView: View {
	@State private var users = ["George", "Kenny", "Susan", "Natalie"]
	
	var body: some View {
		NavigationView {
			List {
				ForEach(users, id: \.self) { user in
					Text(user)
				}
				.onDelete(perform: delete)
			}
			.navigationBarTitle("My family")
			.toolbar {
				EditButton()
			}
		}
	}
	
	func delete(at offsets: IndexSet) {
		users.remove(atOffsets: offsets)
	}
}

Now, I'm doing the following out of curiosity. Now, I have a button in naviationBarItems. And I wonder if I can turn on and off the edit feature of the list with the button?

struct ContentView: View {
	@State private var users = ["George", "Kenny", "Susan", "Natalie"]
	
	var body: some View {
		NavigationView {
			List {
				ForEach(users, id: \.self) { user in
					Text(user)
				}
			}
			
			.navigationBarTitle("My family")
			.navigationBarItems(trailing:
									Button(action: {
										print("Edit button pressed...")
									}) {
										Text("Edit")
									}
			)
		}
	}
}

Muchos thankos.

Answered by OOPer in 687038022

You can try something like this:

struct ContentView: View {
    @State private var users = ["George", "Kenny", "Susan", "Natalie"]
    @State var editMode: EditMode = .inactive //<-
    
    var body: some View {
        NavigationView {
            List {
                ForEach(users, id: \.self) { user in
                    Text(user)
                }
                .onDelete(perform: delete)
            }
            .environment(\.editMode, $editMode) //<-
            .navigationBarTitle("My family")
            .navigationBarItems(trailing:
                Button(action: {
                    print("Edit button pressed...")
                    self.editMode = .active //<-
                }) {
                    Text("Edit")
                }
            )
        }
    }
    
    func delete(at offsets: IndexSet) {
        users.remove(atOffsets: offsets)
    }
}

Create a state representing EditMode and pass the Binding of it to the environment \.editMode of the inner view (List).

You may want to add animating or change the button to Done, but I think you can do it yourself.

Accepted Answer

You can try something like this:

struct ContentView: View {
    @State private var users = ["George", "Kenny", "Susan", "Natalie"]
    @State var editMode: EditMode = .inactive //<-
    
    var body: some View {
        NavigationView {
            List {
                ForEach(users, id: \.self) { user in
                    Text(user)
                }
                .onDelete(perform: delete)
            }
            .environment(\.editMode, $editMode) //<-
            .navigationBarTitle("My family")
            .navigationBarItems(trailing:
                Button(action: {
                    print("Edit button pressed...")
                    self.editMode = .active //<-
                }) {
                    Text("Edit")
                }
            )
        }
    }
    
    func delete(at offsets: IndexSet) {
        users.remove(atOffsets: offsets)
    }
}

Create a state representing EditMode and pass the Binding of it to the environment \.editMode of the inner view (List).

You may want to add animating or change the button to Done, but I think you can do it yourself.

How to Use a Button in navigationBarItems to Work with List
 
 
Q