Search code examples
iosswiftuicollectionviewuicollectionviewcellindexpath

Delete Cell from UICollectionView Without Reloading


My app is listening to a socket event which tells it when there's been an update to the data which is currently being displayed by the collectionView on screen. When this occurs I'd like to remove the cell corresponding to the updated row from the data source, and from the collectionView. I can do this as follows:

  1. filter the data to contain only items with an id different to the id of the updated item
  2. set this new data to be the data used by the collectionView
  3. reload the collectionView

    socket.on(DATA_UPDATE) { (data, ack) in
           if let dat = data[0] as? [String: Any] {
              if let tabId = dat["tabId"] as? Int, let resId = dat["resId"] as? Int {
                 let remainingData = self.data?.filter{ $0.tabId != tabId }
                 if resId == self.restaurant?.id && remainingData?.count != self.data?.count {
                     self.data = remainingData
                     self.filterTableDataAndRelaod()
                 }
              }
           }
        }
    

The problem with this is that it updates the whole collectionView and also scrolls up to the top. I wanted to do this using the following code instead:

self.data.remove(at: indexPath.row)
collectionView.deleteItems(at: [indexPath])

However, I'm not sure how to obtain the indexPath in the above code snippet.


Solution

  • You can try

     var toDele = [IndexPath]()
        if let tabId = dat["tabId"] as? Int, let resId = dat["resId"] as? Int {
           for (index,item) in self.data?.enumerated() {
               if item.tabId == tabId {
                  toDele.append(IndexPath(item:index,section:0)) 
               }
            } 
    
            for item in toDele {
                self.data?.remove(at:item.item)
            }
           collectionView.deleteItems(at:toDele )
      }
    

    or if you don't have duplicates

       if let tabId = dat["tabId"] as? Int, let resId = dat["resId"] as? Int {
           if let ind = self.data?.firstIndex(where:{ $0.tabId == tabId }) {
                self.data?.remove(at:ind) 
                collectionView.deleteItem(at:IndexPath(item:ind,section:0))
           }
       }