SwiftUI EditButton problem in Xcode 12 beta

Created a brand new project with Xcode 12 beta 3. The following code, where I've swapped in for ContentView, works in Xcode 11, but not now. The problem is the List does not go into Edit mode. Cells bounce, but no remove icon (-) appears. The EditButton does change to "Done".

However, one can take any other action - add a cell with the "Add Item" button, or just swiping a cell to reveal "Delete" (don't have to actually delete). After the List has been "kicked" into action, the EditButton will now behave properly.

struct ContentView: View {
    @State var myArray : [String] = ["One", "Two", "Three"]

    func removeItems(at offsets: IndexSet) {
        for index in offsets {
            myArray.remove(at: index)
        }
    }

    var body: some View {
        NavigationView {
            VStack {
                Button(action: {
                    self.myArray.append("Other")
                }) {
                    Text("Insert item")
                }                             

                List {
                    ForEach(myArray, id: \.self) { item in
                        VStack {
                            Text(item)
                        }
                    }.onDelete(perform: removeItems(at:))
                }
            }
            .navigationBarItems(trailing: EditButton())
            .navigationBarTitle("Navigation")
        }
    }
}


Accepted Reply

I think the issue you are describing is resolved in beta 4, which was released today. I can reproduce in beta 3 but not beta 4.

If you are still seeing an issue in beta 4, or for other issues like this, consider filing a bug report using Feedback Assistant.

Replies

This code works for me in Xcode 12 Beta 3.

Code Block Swift
struct ContentView: View {
@State private var myArray: [String] = ["One", "Two", "Three"]
var body: some View {
NavigationView {
VStack {
Button("Insert item") {
myArray.append("Other")
}
List {
ForEach(myArray, id: \.self) { item in
Text(item)
}
.onDelete { indexSet in
myArray.remove(atOffsets: indexSet)
}
}
}
.navigationBarTitle("Navigation")
.navigationBarItems(trailing: EditButton())
}
}
}


Hi. Thanks for trying. I used your code - appreciate it is simpler than mine. Still on Xcode 12 Beta 3. It still exhibits the same problem I saw. Be sure to look at what happens when tapping the EditButton right after compiling - before doing any other table actions. The table tries - one sees a brief jerk - but cannot actually get into edit mode.

Just in case there is a system dependency, I am running on macOS Catalina 10.15.6.
Did some checking with different iOS simulators. Problem shows up on iPhone/iPod devices. Problem shows up on iPad in landscape. For iPad in portrait, one has to hit the back button first to see the screen - and when it reaches the screen, it works ok.
I think the issue you are describing is resolved in beta 4, which was released today. I can reproduce in beta 3 but not beta 4.

If you are still seeing an issue in beta 4, or for other issues like this, consider filing a bug report using Feedback Assistant.
Thank you. Problem is gone in beta 4.
I have the same issue here on XCode Beta 6 (12A8189n).

When:
  1. just having launched the app and then tapping the EditButton() as a first action.

  2. having created a new list item in a modal child view.

The strange thing is that after manipulating the data of the same list by other functions that do nothing else than 2. the EditButton works just fine afterward.

Any ideas?

I still encounter the same issue under Version 12.0.1 of Xcode. I'm running the app on a iPhone 11 directly that is under iOS 14.0.1.

Code Block struct AddCookingStepView: View {
    @Binding var cookingSteps: [CookingStep]
    var body: some View {
        NavigationView{
            Form {
                Section(header: Text("Steps")) {
                        ForEach(cookingSteps) { step in
                            CookingStepRowListView(cookingStep: step)
                        }
                            .onDelete(perform: removeRows)
                            .onMove(perform: moveRows)
                    }
                }
            }
            .navigationBarItems(trailing:
                    EditButton()
            )
        }
    }


I just filed a bug with Apple about this. The problem is in adding the StackNavigationViewStyle to the NavigationView. Run the following code and note that if you immediately click the EditButton the list jumps but does not properly enter edit mode. Then comment out the marked line below and run it again: things work fine.

Code Block swift
struct ContentView: View {
@State private var myArray: [String] = ["One", "Two", "Three"]
var body: some View {
NavigationView {
List {
ForEach(myArray, id: \.self) { item in
Text(item)
}
.onDelete { indexSet in
myArray.remove(atOffsets: indexSet)
}
}
.navigationTitle("My List")
.navigationBarItems(trailing: EditButton())
}
.navigationViewStyle(StackNavigationViewStyle()) // Comment this out and the problem goes away.
}
}

The problem is ForEach with id: \.self for a dynamic array of value types is a major mistake unfortunately made by many developers, anyone know why? The documentation states that id needs to be "The key path to the provided data’s identifier." E.g. id: \.uniqueIdentifier, or preferably conform your model struct to Identifiable and implement either let id = UUID() or var id: String { return a calculated id from other vars }