Duck
Duck

Reputation: 35953

Element on TabView does not disappear after being deleted

I have this class:

class PageViewModel:ObservableObject {
  @Published var cars = [Car]()   
  
  func delete(_ car:Car) {
    cars = cars.filter { $0 != car }
  }
  
}

Then I pass this class to a view called PageView, like this

@ObservedObject private var pageViewModel = PageViewModel()

var body: some View {
  PageView(pageViewModel)

This is PageView:

struct PageView: View {
  @ObservedObject private var pageViewModel:PageViewModel
  
  init(_ pageViewModel:PageViewModel) {
    self.pageViewModel = pageViewModel
  }
  
  var body: some View {
    TabView() {
      ForEach(pageViewModel.cars) { car in
        TopPanel(car, pageViewModel)
          .frame(maxWidth: .infinity)
          .padding([.leading, .trailing], 10)
          .padding(.bottom,60)
        
      }
    }
    .frame(height: 220)
    .tabViewStyle(PageTabViewStyle())
    .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
  }
}

Note: Car is a NSManagedObject, so it is @ObservableObject by default. Here it is

Car+CoreDataClass.swift

import Foundation
import CoreData

@objc(Car)
public class Car: NSManagedObject {
}

Car+CoreDataProperties

extension Car : Encodable {
  
  @nonobjc public dynamic class func fetchRequest() -> NSFetchRequest<Car> {
    return NSFetchRequest<Car>(entityName: "Car")
  }
  
  @NSManaged public var model: String?
  @NSManaged public var brand: String?

This is TopPanel and where the problem originates.

struct TopPanel: View {
@ObservedObject private var car:Car
@ObservedObject private var pageViewModel:PageViewModel
  
init(_ car:Car,
     _ pageViewModel:PageViewModel?) {
  self.car = car
  self.pageViewModel = model
}

var body: some View {
  Button(action: {
    pageViewModel.delete(car)
}, label: {
  Text("delete me")
})

Remember that the TabView is showing pages of TopPanel and this TopPanel has a button that allows the user to delete itself from the TabView.

The problem is that when I press delete on a given element, it continues to show on the TabView but one the dots on the TabView is deleted. If after that I try to delete a second one, I receive this message:

*** Assertion failure in -[_TtC7SwiftUIP33_8825076C2763A50452A210CBE1FA4AF020PagingCollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:collectionViewAnimator:], UICollectionView.m:6982

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete and reload the same index path (<NSIndexPath: 0xacce8bbd6a5ce2d8> {length = 2, path = 0 - 1})'

How do I solve that?

Upvotes: 3

Views: 218

Answers (1)

Duck
Duck

Reputation: 35953

Unbelievable, I have discovered how to solve this, completely by chance.

Just add

    .id(pageViewModel.cars.count)

to the TabView. That will force it to update when an item is deleted.

Upvotes: 2

Related Questions