UITableView & UICollectionView have some fantastic animation capabilities. We can animate items and sections being inserted, removed, moved, etc. We've all been there though, reloadData is sitting right there, and is conceptually so simple. Wouldn't it be great if we could enable those fancy animations in our views, with the conceptually simplicity of reloadData?

Today we'll check out Dwifft, a library from Jack Flintermann that can help us achieve this. Let's dive in.

We'll begin with a regular UITableViewController. (Dwifft works just as well on UICollectionViews).

First we'll need a TableViewDiffCalculator. This is a generic type, so we'll tell it that we're going to be display a bunch of Strings.

class ExampleViewController: UITableViewController {
  var diffCalculator: TableViewDiffCalculator<String>?

Next we'll initialize our data with some random items (just a randomly ordered array of Strings). We'll also use a property observer to let our diff calculator know whenever our items change.

var items: [String] = ExampleViewController.randomItems() {
  didSet { self.diffCalculator?.rows = items }
}

We're almost there. We'll initialize the diff calculator in our view controller's viewDidLoad function:

override func viewDidLoad() {
  super.viewDidLoad()

  tableView.register(UITableViewCell.self, forCellReuseIdentifier: "ItemCell")

  diffCalculator = TableViewDiffCalculator<String>(
    tableView: tableView,
    initialRows: items
  )
}

Lastly, we'll implement a couple of standard UITableViewDataSource functions:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  return items.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
  cell.textLabel?.text = selfitems[(indexPath as NSIndexPath).row]
  return cell
}

Success! Here's how this ends up looking:

The "Shuffle" button was wired up off-camera, but it simply sets self.items = ExampleViewController.randomItems().

Now we can simply update the diff calculator's rows and we'll get all those beautiful, scroll-position preserving animations automatically.

A couple of final notes, we can customize the individual animation types like this:

diffCalculator?.insertionAnimation = .fade
diffCalculator?.deletionAnimation = .fade

And finally for fun the science behind Dwifft is pretty neat to read about. Read more about the Longest Common Subsequence Problem here.

Learn more about Dwifft at git.io/dwifft