How to do Clear-style swiping in iOS tables

Feb 15, 2012 12:52 · 615 words · 3 minute read iOS tableViews

The latest app that everyone’s raving about is Clear - if you haven’t seen it, it’s basically a task list, but one with a rather interesting take on the interface. Instead of the usual tab-bar-and-table-vew setup, the table is full-screen and makes extensive use of gestures.

Deleting and completing tasks are done by swiping the row - a left swipe deletes the item, a right swipe marks it as complete. Here’s the basis of how that’s done.

The effect relies on the cell’s contentView having two UIViews “stacked” one on top of the other, and a pair of UISwipeGestureRecognizers attached to the cell - one for left swipes, and one for right swipes. When a swipe is detected, the uppermost UIView is animated left or right to “reveal” the UIView that sits “underneath”. By chaining the animations together with UIView animation blocks, you can also do things like make the animations “bounce” at each end of their range of movement.

The outline process runs like this:

  1. Create a UITableView and wire up with delegate and data source as per usual.

  2. Create a custom UITableViewCell class, and override the initWithStyle:reuseIdentifer: method to lay out the UIViews inside it. Then implement the animation methods in the custom cell’s subclass, and add the UISwipeGestureRecognizers.

  3. Populate your table with instances of your custom UITableViewCell.

The first and third steps are pretty routine, so don’t really need much explanation. The magic, such as it is, happens within the UITableViewCell subclass. The initWithStyle:reusedIdentifier: method can be used to lay out the contents of the cell and set up the UISwipeGestureRecognizers - here’s a sample method:

{% gist 1835423)

This is fairly verbose, but breaks down into four stages:

  1. creating the top view, which is the one which is viewable when the cell is in the “normal” state

  2. creating the bottom view, which is the one that gets revealed when the top view moves

  3. adding these two views to the cell’s contentView

  4. creating and adding two UISwipeGestureRecognizers to the cell and using these to fire the animation methods.

The animation is done by two methods in the cell subclass, one for right and one for left. Here’s the detail of the rightward-swipe method:

[gist id=1835417]

It uses UIView's block-based animatedWithDuration:animations: method to chain together a series of moves to give a “bounce” effect - the view that’s doing the movement “overshoots” the end position slightly, and then settles back. The durations in this code are deliberately long to show the effect, but when they’re shorted in practice the bounce effect can really liven up the interface.

In the case of Clear, the swipe gesture methods also trigger updates to the tableView’s data model to mark the task as completed (or deleting it). At a rough guess, there’s a separate section of the table for deleted items that uses another custom UITableViewCell subclass to style the items with the strikethrough and dark background.

The swipe effects are a nice detail in the Clear app, and it’s a great example of how gestures can be used in place of more traditional tap-based interactions. The tradeoff is that the interactions are less apparent - the call to action of a Delete button is obvious, whereas a gesture has to be either explicitly explained or discovered. It’ll be interesting to see if this is the start of a pattern in app design.

[I’ve put an example app that’s a full implementation of the swipe interactions shown above up on GitHub at https://github.com/timd/SwipingTable . And the full process is shown in detail in my book, for which this is a shameless plug (well, if I can’t promote it on my own blog, where can I? ;-) ]