2

I have a view CountriesListScreen, to which I am passing a list of items.

struct CountriesListScreen: View {
  var listItems: CountriesListItems

  var body: some View {
    VStack {

      Section(header: CountriesListHeader()) {
        ForEach (listItems, id: .name) { item in
            ...
        }
      }

    }
  }

}

This is what I am doing:

  • I am first displaying CountriesListScreen, with 9 list items
  • I then go to another view, where I perform an action, which modifies the list of items
  • I then go back to CountriesListScreen, passing the new listItems object, which has now 5 items instead of 9

I am getting this NSInternalInconsistencyException, which I don’t know how to solve:

*** Assertion failure in -[_TtC7SwiftUIP33_BFB370BA5F1BADDC9D83021565761A4925UpdateCoalescingTableView
_Bug_Detected_In_Client_Of_UITableView_Invalid_Number_Of_Rows_In_Section:],
UITableView.m:2471 2021-06-11 18:22:55.908398+0300
iosApp[6525:5802640] *** Terminating app due to uncaught exception
‘NSInternalInconsistencyException’, reason: ‘Invalid update: invalid
number of rows in section 0. The number of rows contained in an
existing section after the update (9) must be equal to the number of
rows contained in that section before the update (9), plus or minus
the number of rows inserted or deleted from that section (0 inserted,
4 deleted) and plus or minus the number of rows moved into or out of
that section (0 moved in, 0 moved out).’

If I understand correctly, SwiftUI triggers the error, as it realizes that the list of items has changed, and the change hasn’t happened within the view.

How can I safely, redraw the list with a different number of items, without having this error triggered?

UPDATE: (giving more context)

The views involved are 3:

  1. the parent of CountriesListScreen, let’s call it MainView, which references an ObservedObject, which has listItems as a property
  2. CountriesListScreen, which receives listItems as a parameter from its parent
  3. a third view, which performs an action that modifies the listItems (and hence the ObservedObject), triggering an update of the MainView