ios - Updating UICollectionView after deleting a Realm object -


when try delete item realm database unable update uicollection view appropriately.

lets assume realm container children of type list<child>:

var children = realm.objects(parent).first!.children  

when want remove child database by:

try! realm.write {     realm.delete(children[indexpath.row]) } 

updating collectionview collectionview.deleteitemsatindexpaths([indexpath]) gives following error:

got error: *** terminating app due uncaught exception 'rlmexception', reason: 'object has been deleted or invalidated.' 

the way collectionview updated using collectionview.reloaddata(), not want since animation of cell deletion missing.

however, when remove child container @ indexpath.row (without removing database) by:

try! realm.write {     children.removeatindex(indexpath.row) } 

updating collectionview collectionview.deleteitemsatindexpaths([indexpath]) works without problems.

what best way update uicollectionview after removing item database?

the error you're facing appears when keep accessing object, deleted. so, you're storing somewhere reference object, fine per se, keep accessing after invalidated.

that happen e.g. in custom subclass of uicollectionviewcell. i'd recommend implement setter on cell , pull method property values view components. can use kvo in cell update these. (we've an example based on reactkit in our repo.) can't though keep accessing properties when object might deleted @ later point in time, e.g. if cell needs drawn or layout when faded out.

i'd recommend subscribe fine-grained notifications list you're using fill collection view's cells , propagate updates in way collection view. in way can make sure items removed nice animation requested , automatically taken care of. put seen below. on @ our repo, you'll find complete runnable sample.

class cell: uicollectionviewcell {     @iboutlet var label: uilabel!      func attach(object: demoobject) {         label.text = object.title     } }  class collectionviewcontroller: uicollectionviewcontroller {     var notificationtoken: notificationtoken? = nil      lazy var realm = try! realm()     lazy var results: results<demoobject> = {         self.realm.objects(demoobject)     }()       // mark: view lifecycle      override func viewdidload() {         super.viewdidload()          // observe notifications         notificationtoken = results.addnotificationblock { [weak self] (changes: realmcollectionchange) in             guard let collectionview = self?.collectionview else { return }             switch changes {             case .initial:                 // results populated , can accessed without blocking ui                 collectionview.reloaddata()                 break             case .update(_, let deletions, let insertions, let modifications):                 // query results have changed, apply them uitableview                 collectionview.performbatchupdates({                     collectionview.insertitemsatindexpaths(insertions.map { nsindexpath(forrow: $0, insection: 0) })                     collectionview.deleteitemsatindexpaths(deletions.map { nsindexpath(forrow: $0, insection: 0) })                     collectionview.reloaditemsatindexpaths(modifications.map { nsindexpath(forrow: $0, insection: 0) })                 }, completion: { _ in })                 break             case .error(let error):                 // error occurred while opening realm file on background worker thread                 fatalerror("\(error)")                 break             }         }     }      deinit {         notificationtoken?.stop()     }       // mark: helpers      func objectatindexpath(indexpath: nsindexpath) -> demoobject {         return results[indexpath.row]     }       // mark: uicollectionviewdatasource      override func collectionview(collectionview: uicollectionview, numberofitemsinsection section: int) -> int {         return results.count     }      override func collectionview(collectionview: uicollectionview, didselectitematindexpath indexpath: nsindexpath) {         let object = objectatindexpath(indexpath)         try! realm.write {             realm.delete(object)         }     }      override func collectionview(collectionview: uicollectionview, cellforitematindexpath indexpath: nsindexpath) -> uicollectionviewcell {         let object = objectatindexpath(indexpath)         let cell = collectionview.dequeuereusablecellwithreuseidentifier("cell", forindexpath: indexpath) as! cell         cell.attach(object)         return cell     }  } 

Comments

Popular posts from this blog

wordpress - (T_ENDFOREACH) php error -

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

Using django-mptt to get only the categories that have items -