NEW: Start my new Ultimate Portfolio App course with a free Hacking with Swift+ trial! >>

SOLVED: Conditionally add an onDelete() function to item(s) fails with strange results

Forums > SwiftUI

The code below presents a number of 'event' items in a from. Each item can be deleted or clicked on to navugate to a different view:

private func addDetails() -> some View {
        Form {

            Section(header: Text("Events").font(.headline)) {
                ForEach(eventArray, id: \.self) { event in
                    NavigationLink(destination: EventDetailView(event: event)) {
                        HTextPair(labelText: event.wrappedType,
                                  valueText: event.formattedDate)
                    }
                }.onDelete(perform: deleteEvent)
          }
    }

I would like to prevent deletion of events unless the user has clicked on a custom 'Edit/Done' button on the navigation bar which simply toggles a boolean flag isEditing. I believe that the following code should work:

private func addDetails() -> some View {
    Form {

        Section(header: Text("Events").font(.headline)) {
            if isEditing {
                ForEach(eventArray, id: \.self) { event in
                    NavigationLink(destination: EventDetailView(event: event)) {
                        HTextPair(labelText: event.wrappedType,
                              valueText: event.formattedDate)
                    }
                }.onDelete(perform: deleteEvent)
            } else {
                ForEach(eventArray, id: \.self) { event in
                    NavigationLink(destination: EventDetailView(event: event)) {
                        HTextPair(labelText: event.wrappedType,
                                  valueText: event.formattedDate)
                    }
                } 
            }
        }
    }
}

With this revised version the everythin works as expected when isEditing == false . When isEditing == true navigation no longer works and only the last item becomes deletable.

I have also tried placing the items inside a List but that does not render correctly - the List takes up a single line. Is there a better way to conditionally enable/disable delete for each item?

   

To make things easier for you do the following (I have just cut and copied your first section of code and made a very small change to get what you want) -

private func addDetails() -> some View {
        Form {

            Section(header: Text("Events").font(.headline)) {
                ForEach(eventArray, id: \.self) { event in
                    NavigationLink(destination: EventDetailView(event: event)) {
                        HTextPair(labelText: event.wrappedType,
                                  valueText: event.formattedDate)
                    }
                }.onDelete(perform: isEditing ? deleteEvent : nil) // Here is the change just make a ternary in onDelete using your isEditing boolean. Will do nothing if isEditing is false.
          }
    }

Hope this suites you :)

   

Thanks - that has solved the problem but I still don't understand the cause of the unexpected behaviour..

My gut feel is that SwiftUI is very buggy and possible requires anoth 18months development by Apple before it is suitable for creating anything more complex than a simple UI. A lotsof things do not work as expected and require work arounds. I found that if I place I show an ImagePicker sheet over a Form which has a small MapView as one of its elements, the program crashes with a Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) the fix is to load the ImagePicker from a different pane.

Currently I am having another issue with applying my isEditing flag in a view. This time it is to enable or disable a 'NavigationLink'

            VStack(alignment: .leading) {

                NavigationLink(destination: AddEventAttributeView(
                viewModel: viewModel, candidate: event)) {
                    Text("Add Attribute")
                }//.disabled(!isEditing)

            }
            //.disabled(!isEditing)

If I uncomment either of the ,disabled(!isEditing) line in the above code the link changes appearance for active / inactive but has no affect. With the line commented out the link works but I do not want to allow modification unless the user is editing.

   

Hacking with Swift is sponsored by Essential Developer

SPONSORED From January 26th to 31st you can join a FREE crash course for iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a senior developer!

Save your spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.