Delete Cells From A Set

I'm trying to add delete functionality to my app and I am wondering how I can fix this error Cannot use mutating member on immutable value: 'favSet' is a get-only property.

class FavouriteManager {
   
   
  static let shared = FavouriteManager()
   
  var favSet: OrderedSet<CurrentPlayers> = OrderedSet()
   
  func add(_ player: CurrentPlayers) {
    favSet.append(player)
    NotificationCenter.default.post(
      name: .passFavNotification,
      object: player
    )
  }
}
   var favSet: OrderedSet<CurrentPlayers> {
    FavouriteManager.shared.favSet
  }

   //delete function 
   override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
      tableView.beginUpdates()
      favSet.remove(at: favSet.index(favSet.startIndex, offsetBy: indexPath.row)) //this is where the error is
      tableView.deleteRows(at: [indexPath], with: .fade)
      tableView.endUpdates()
    }
  }

Replies

The problem is you declare only a get for favSet in the computed var

   var favSet: OrderedSet<CurrentPlayers> {
    FavouriteManager.shared.favSet
  }

Declare get and set and that will work.

Why don't you use an Array and manage to eliminate duplicate entries in the array ?when you append to it (just test if the new entry is already inside).

Okay I guess I can turn it into an array it would make it so much simpler. I really don't understand how to set it.

you could just add a setter

var favSet: OrderedSet<CurrentPlayers> {
    get { FavouriteManager.shared.favSet }
    set { print("New value", newValue)  }  // print just to see ; could be no statement
  }

Okay I have another error with deleting: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

What is the tableView dataSource ? It must be updated before deleteRow. If the dataSource is FavouriteManager.shared.favSet, you must update it as well:

    if editingStyle == .delete {
      tableView.beginUpdates()
      favSet.remove(at: favSet.index(favSet.startIndex, offsetBy: indexPath.row))
      FavouriteManager.shared.favSet = favSet   // I do not know how you defined, can't be sure it will work
      tableView.deleteRows(at: [indexPath], with: .fade)
      tableView.endUpdates()
    }

Please show all delegate func for the tableView, in particular cellForRow

Okay I will show you that I still have same issue.

   override func numberOfSections(in tableView: UITableView) -> Int {
     return 1
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return favSet.count
  }
   
   
  override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 152
  }
   
   
  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "favcell", for: indexPath) as! FavCell
    let itemFav = favSet[favSet.index(favSet.startIndex, offsetBy: indexPath.row)]
    cell.layer.borderColor = UIColor.black.cgColor
    cell.layer.borderWidth = 0.5
    cell.contentView.backgroundColor = .random

    cell.update(with: itemFav)
    return cell
  }

So your dataSource is favSet. But you get it from the shared.

I would try:

var favSet: OrderedSet<CurrentPlayers> {
    get { FavouriteManager.shared.favSet }
    set { FavouriteManager.shared.favSet =  newValue  }  
  }

and revert to the .delete:

  if editingStyle == .delete {
      tableView.beginUpdates()
      favSet.remove(at: favSet.index(favSet.startIndex, offsetBy: indexPath.row))
      tableView.deleteRows(at: [indexPath], with: .fade)
      tableView.endUpdates()
    }