@@ -11,10 +11,10 @@ import Combine
1111public class TableViewItemsController < CollectionType> : NSObject , UITableViewDataSource
1212 where CollectionType: RandomAccessCollection ,
1313 CollectionType. Index == Int ,
14- CollectionType. Element: Equatable ,
14+ CollectionType. Element: Hashable ,
1515 CollectionType. Element: RandomAccessCollection ,
1616 CollectionType. Element. Index == Int ,
17- CollectionType. Element. Element: Equatable {
17+ CollectionType. Element. Element: Hashable {
1818
1919 public typealias Element = CollectionType . Element . Element
2020 public typealias CellFactory < Element: Equatable > = ( TableViewItemsController < CollectionType > , UITableView , IndexPath , Element ) -> UITableViewCell
@@ -70,35 +70,18 @@ public class TableViewItemsController<CollectionType>: NSObject, UITableViewData
7070 // Commit the changes to the table view sections
7171 tableView. beginUpdates ( )
7272 for sectionIndex in 0 ..< items. count {
73+ let rowAtIndex = fromRow ( sectionIndex)
7374 let changes = delta ( newList: items [ sectionIndex] , oldList: collection [ sectionIndex] )
74- tableView. deleteRows ( at: changes. removals. map ( fromRow ( sectionIndex) ) , with: rowAnimations. delete)
75- tableView. insertRows ( at: changes. insertions. map ( fromRow ( sectionIndex) ) , with: rowAnimations. insert)
75+ tableView. deleteRows ( at: changes. removals. map ( rowAtIndex) , with: rowAnimations. delete)
76+ tableView. insertRows ( at: changes. insertions. map ( rowAtIndex) , with: rowAnimations. insert)
77+ for move in changes. moves {
78+ tableView. moveRow ( at: rowAtIndex ( move. 0 ) , to: rowAtIndex ( move. 1 ) )
79+ }
7680 }
7781 collection = items
7882 tableView. endUpdates ( )
7983 }
8084
81- private func delta< T> ( newList: T , oldList: T ) -> ( insertions: [ Int ] , removals: [ Int ] )
82- where T: RandomAccessCollection , T. Element: Equatable {
83-
84- let changes = newList. difference ( from: oldList)
85-
86- let insertIndexes = changes. compactMap { change -> Int ? in
87- guard case CollectionDifference < T . Element > . Change . insert( let offset, _, _) = change else {
88- return nil
89- }
90- return offset
91- }
92- let deleteIndexes = changes. compactMap { change -> Int ? in
93- guard case CollectionDifference < T . Element > . Change . remove( let offset, _, _) = change else {
94- return nil
95- }
96- return offset
97- }
98-
99- return ( insertions: insertIndexes, removals: deleteIndexes)
100- }
101-
10285 // MARK: - UITableViewDataSource protocol
10386 public func numberOfSections( in tableView: UITableView ) -> Int {
10487 guard collection != nil else { return 0 }
@@ -132,3 +115,29 @@ public class TableViewItemsController<CollectionType>: NSObject, UITableViewData
132115 return dataSource
133116 }
134117}
118+
119+ internal func delta< T> ( newList: T , oldList: T ) -> ( insertions: [ Int ] , removals: [ Int ] , moves: [ ( Int , Int ) ] )
120+ where T: RandomAccessCollection , T. Element: Hashable {
121+
122+ let changes = newList. difference ( from: oldList) . inferringMoves ( )
123+
124+ var insertions = [ Int] ( )
125+ var removals = [ Int] ( )
126+ var moves = [ ( Int, Int) ] ( )
127+
128+ for change in changes {
129+ switch change {
130+ case . insert( offset: let index, element: _, associatedWith: let associatedIndex) :
131+ if let fromIndex = associatedIndex {
132+ moves. append ( ( fromIndex, index) )
133+ } else {
134+ insertions. append ( index)
135+ }
136+ case . remove( offset: let index, element: _, associatedWith: let associatedIndex) :
137+ if associatedIndex == nil {
138+ removals. append ( index)
139+ }
140+ }
141+ }
142+ return ( insertions: insertions, removals: removals, moves: moves)
143+ }
0 commit comments