Collection Update

16bebb36e0e28572a316ba0450e190d1?s=47 Khoa Pham
November 27, 2017

Collection Update

Demo how UITableView, UICollection performs batch update

16bebb36e0e28572a316ba0450e190d1?s=128

Khoa Pham

November 27, 2017
Tweet

Transcript

  1. Collection Update

  2. About —khoa@hyper.no —https://github.com/onmyway133 —https://github.com/hyperoslo

  3. Content —TableView / CollectionView —Drag and Drop —Let's play some

    games ! —Diff
  4. NSCollectionView !

  5. Newsloop

  6. Drag and Drop Demo !

  7. index vs offset Array(0..<10).enumerated().forEach { (offset, element) in } -

    https://en.wikipedia.org/wiki/Zero-based_numbering - offset from the starting position
  8. NSInternalInconsistencyException Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid

    update: invalid number of items in section 0. The number of items contained in an existing section after the update (213) must be equal to the number of items contained in that section before the update (154), plus or minus the number of items inserted or deleted from that section (40 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).'
  9. Game of IndexPath —https://github.com/onmyway133/ CollectionUpdateExample —10 quizzes items = ["a",

    "b", "c", "d", "e", "f"]
  10. 1) insert 3 items at the end items.append(contentsOf: ["g", "h",

    "i"]) // a, b, c, d, e, f, g, h, i let indexPaths = Array(6...8).map { IndexPath(item: $0, section: 0) } collectionView.insertItems(at: indexPaths)
  11. 2) delete 3 items at the end items.removeLast() items.removeLast() items.removeLast()

    // a, b, c let indexPaths = Array(3...5).map { IndexPath(item: $0, section: 0) } collectionView.deleteItems(at: indexPaths)
  12. 3) update item at index 2 items[2] = " !

    " // a, b, ! , d, e, f let indexPath = IndexPath(item: 2, section: 0) collectionView.reloadItems(at: [indexPath])
  13. 4) move item "c" to the end items.remove(at: 2) items.append("c")

    // a, b, d, e, f, c collectionView.moveItem( at: IndexPath(item: 2, section: 0), to: IndexPath(item: 5, section :0) )
  14. 5) delete 3 items at the beginning, then insert 3

    items at the end items.removeFirst() items.removeFirst() items.removeFirst() items.append(contentsOf: ["g", "h", "i"]) // d, e, f, g, h, i collectionView.performBatchUpdates({ let deleteIndexPaths = Array(0...2).map { IndexPath(item: $0, section: 0) } collectionView.deleteItems(at: deleteIndexPaths) let insertIndexPaths = Array(3...5).map { IndexPath(item: $0, section: 0) } collectionView.insertItems(at: insertIndexPaths) }, completion: nil)
  15. 6) insert 3 items at the end, then delete 3

    items beginning items.append(contentsOf: ["g", "h", "i"]) items.removeFirst() items.removeFirst() items.removeFirst() // d, e, f, g, h, i collectionView.performBatchUpdates({ let insertIndexPaths = Array(6...8).map { IndexPath(item: $0, section: 0) } collectionView.insertItems(at: insertIndexPaths) let deleteIndexPaths = Array(0...2).map { IndexPath(item: $0, section: 0) } collectionView.deleteItems(at: deleteIndexPaths) }, completion: nil)
  16. ! Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt

    to insert item 6 into section 0, but there are only 6 items in section 0 after the update'
  17. performBatchUpdates Deletes are processed before inserts in batch operations

  18. 6) insert 3 items at the end, then delete 3

    items beginning ! items.append(contentsOf: ["g", "h", "i"]) items.removeFirst() items.removeFirst() items.removeFirst() // d, e, f, g, h, i collectionView.performBatchUpdates({ let deleteIndexPaths = Array(0...2).map { IndexPath(item: $0, section: 0) } collectionView.deleteItems(at: deleteIndexPaths) let insertIndexPaths = Array(3...5).map { IndexPath(item: $0, section: 0) } collectionView.insertItems(at: insertIndexPaths) }, completion: nil)
  19. Operations insertItems(at indexPaths: [IndexPath]) deleteItems(at indexPaths: [IndexPath]) reloadItems(at indexPaths: [IndexPath])

    moveItem(at indexPath: IndexPath, to newIndexPath: IndexPath) performBatchUpdates(_ updates, completion) insertSections(_ sections: IndexSet) deleteSections(_ sections: IndexSet) reloadSections(_ sections: IndexSet) moveSection(_ section: Int, toSection newSection: Int)
  20. Ordering of Operations and Index Paths —https://developer.apple.com/library/content/ documentation/UserExperience/Conceptual/ TableView_iPhone/ManageInsertDeleteRow/ ManageInsertDeleteRow.html

  21. Wagner–Fischer algorithm —https://en.wikipedia.org/wiki/ Wagner%E2%80%93Fischer_algorithm —https://en.wikipedia.org/wiki/ Dynamic_programming Computes the edit distance

    between two strings of characters.
  22. "kit" -> "kat"

  23. Deletions "k" -> "" ! 1 deletion "ki" -> ""

    ! 2 deletions "kit" -> "" ! 3 deletions
  24. Insertions "" -> "k" ! 1 insertion "" -> "ka"

    ! 2 insertions "" -> "kat" ! 3 insertions
  25. If equal, take value from the top left

  26. horizonally: insertion vertically: deletion diagonally: substitution If not equal, check

    minimum value from left, top, top left. Then increase by one
  27. "k" -> "kat" ! 2 insertions

  28. It equals again, take value from top left. Bottom right

    value gives edit distance (number of steps) "kit" -> "kat" ! Substitute "i" with "a"
  29. insertions: insertItems deletions: deleteItems substitutions: reloadItems move: deletion + insertion

    moveItem
  30. Edit steps —delete, insert, move, substitute —https://github.com/onmyway133/DeepDiff

  31. Complexity —O(mn) —10k items ! Performance —Collection size —Equatable —Hashable

  32. Alternatives —Heckel http://documents.scribd.com/docs/ 10ro9oowpo1h81pgh1as.pdf —Wu https://publications.mpi-cbg.de/ Wu19906334.pdf —Myers http://www.xmailserver.org/diff2.pdf

  33. Q & A Thanks for listening. Hope you have a

    great time