18

How I can use a button like EditButton?
Or how I can use a button to active edit mode from list?
Or how I can change the name from EditButton "edit" / "done"?

3
  • You may want to clarify your question. Are you referring (only) to the title of the button? Or do you want to know how to enter the edit mode of a List? Or both? (In that case you may want to create a separate question). Plus what have you tried so far? Can you share some code? Commented Aug 4, 2019 at 6:39
  • I mean both.. i want active the edit mode for the list with a button like editbutton, I know i can use the editbutton but I want use other designe.. not („edit“/„done“) I want rename this or take a image, so I have to use a button. Commented Aug 5, 2019 at 7:19
  • I updated my answer accordingly, please take a look. Commented Aug 5, 2019 at 8:29

5 Answers 5

30

The implementation below replaces EditButton's functionality with a Button:

import SwiftUI

struct ContentView: View {

    @State var isEditing = false
    @State var selection = Set<String>()

    var names = ["Karl", "Hans", "Faustao"]

    var body: some View {
        NavigationView {
            VStack {
                List(names, id: \.self, selection: $selection) { name in
                    Text(name)
                }
                .navigationBarTitle("Names")
                .environment(\.editMode, .constant(self.isEditing ? EditMode.active : EditMode.inactive)).animation(Animation.spring())
                Button(action: {
                    self.isEditing.toggle()
                }) {
                    Text(isEditing ? "Done" : "Edit")
                        .frame(width: 80, height: 40)
                }
                .background(Color.yellow)
            }
            .padding(.bottom)
        }
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

Result

result

However, by doing so, selection handling needs to be implemented by our own (which may or may not be an issue).

Unfortunately there isn't much documentation around that at this point: https://developer.apple.com/documentation/swiftui/list/3367016-init

Sign up to request clarification or add additional context in comments.

4 Comments

the smooth animation can u active with this code .environment(\.editMode, .constant(self.isEditing ? EditMode.active : EditMode.inactive)).animation(Animation.spring())
Great! Nice tip on ".animation...". I didn't know about that. I updated the answer to include this info. 👍🏻 Please accept it: meta.stackexchange.com/a/5235/219412 Thanks.
This is so helpful. I've had an issue for months where an EditButton would stop working after closing a modal sheet. It's some sort of combination of the EditButton, the edit mode state, and the order in which redraw on screen when closing the modal. I replaced the edit mode and button with this and it's finally working as desired. Thanks a ton!
Using the .constant() binding in the .environment() view modifier caused crashes in my code, see this answer: stackoverflow.com/a/68938630/1085556
13

Here's a way to preserve EditButton's functionality while still observing changes.

EditButton()
    .simultaneousGesture(TapGesture().onEnded {
        // Do your thing
    })

This works for every view on which you want to observe taps.

Comments

7

There is a better way to do this in Beta 5, where you can grab the @Environment binding directly (also better to make this a navigation bar item):

import SwiftUI

struct EditableListView: View {

    @State var items: [String] = ["1", "2", "3"]
    @State var selections: Set<String> = []

    @Environment(\.editMode) private var editMode: Binding<EditMode>

    var body: some View {
        List(items, id: \.self, selection: $selections) { item in
            Text(item)
        }
        .navigationBarItems(trailing:
            Button(action: {
                self.editMode?.value.toggle()
            }) {
                Text(self.editMode?.value == .active ? "Done" : "Edit")
            }
        )
        .animation(.default)
    }
}

extension EditMode {

    mutating func toggle() {
        self = self == .active ? .inactive : .active
    }
}

EditableListAnimation

2 Comments

it does not work for me.. when i click the button then he dont do anything
as solo View. if i do it as second view and open ur code as navigationlink then its ur code well. Thanks
6

As for Xcode 13, there seems to be some update. I test the following code works.

@State var editMode: EditMode = .inactive
@State var isEditing = false

List {
    // (your list code here)
}.environment(\.editMode, $editMode)

Button(action: {
    isEditing.toggle()
    editMode = isEditing ? .active : .inactive
})

1 Comment

Thank you! I was even able to use this method with editMode as an @ObservedObject property in my own controller object outside of SwiftUI.
1

You can also use a normal button like the following :

    .navigationBarItems(trailing: HStack{
        Button(action: {
            editMode?.wrappedValue.toggle()
        }, label: {
            Text(editButtinTxt)
        })
    })

and the text :

var editBtnTxt : String {
    
    if let isEditing = editMode?.wrappedValue.isEditing {
        return isEditing ? "Done" : "Edit"
    }else {
        return ""
    }
}

and don't forget

@Environment(\.editMode) var editMode

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.