Skip to content

Instantly share code, notes, and snippets.

@ahmattox
Created July 12, 2016 17:10
Show Gist options
  • Save ahmattox/9c2c6e49305f7a822578416ffcc4772a to your computer and use it in GitHub Desktop.
Save ahmattox/9c2c6e49305f7a822578416ffcc4772a to your computer and use it in GitHub Desktop.
extension UITableView {
func animateSection<Element: Equatable>(section: Int, from:[Element], to: [Element], rowAnimation: UITableViewRowAnimation = .Top) {
assert(from.containsUniqueElements() && to.containsUniqueElements(), "\(#function) can only be used if all elements in the collection are unique.")
func path(index: Int) -> NSIndexPath {
return NSIndexPath(forRow: index, inSection: section)
}
// Find indexes in the old array that should be deleted
let deletedIndices = from.enumerate().flatMap { index, oldElement in
return to.contains(oldElement) ? nil : index
}
// Find indexes of new objects inserted into the destination array
let insertedIndices = to.enumerate().flatMap { index, newElement in
return from.contains(newElement) ? nil : index
}
// Find indexes in the source array of elements that have not been deleted
let retainedIndices = from.enumerate().flatMap { index, oldElement in
return to.contains(oldElement) ? index : nil
}
// Find the indexes in the source and destination arrays of any moved elements.
let movements: [(Int, Int)] = retainedIndices.flatMap { (movedFromIndex) -> (Int, Int)? in
let movement = (movedFromIndex, to.indexOf(from[movedFromIndex])!)
return (movement.0 != movement.1) ? movement : nil
}
beginUpdates()
deleteRowsAtIndexPaths(deletedIndices.map { path($0) }, withRowAnimation: rowAnimation)
insertRowsAtIndexPaths(insertedIndices.map { path($0) }, withRowAnimation: rowAnimation)
for movement in movements {
moveRowAtIndexPath(path(movement.0), toIndexPath: path(movement.1))
}
endUpdates()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment