Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 635
Duck Avatar asked Jan 18 '26 22:01

Duck


1 Answers

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.

like image 74
Duck Avatar answered Jan 21 '26 12:01

Duck



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!