all micro contact rss

The Power of the Pan

Way back when I shipped Fin 1.0, it wasn’t very easy to set the timer to anything except a small set of presets. The presets weren’t even editable.[1]

The only way to set a timer for anything beyond the presets was to swipe up or down to add or subtract one minute at a time. You could change the increments in settings—to make it two minutes, or five minutes, or whatever, per swipe—but this gesture was always meant for quick adjustments, not as the primary way to set the time.

To make matters worse, because I wasn’t very skilled at code at that point, I did what many developers do: I punted by using UISwipeGestureRecognizer rather than implementing a UIPanGestureRecognizer.[2]

Later, when I added an animation to bounce the time label up or down with the swipe, and I still left it as a swipe gesture, that really didn’t sit well with me.

A swipe is almost never a simple yes or no. You want your interface to react to the swipe as it’s happening, which usually means moving something on the screen in a similar direction to your finger movement. A swipe gesture recognizer is incapable of reacting in real time.

In this case, I wanted the time label to move in concert with the motion of your finger. But all I could do with a swipe gesture was wait until it recognized the swipe and then move the label. If you swiped fast enough and with conviction, it almost felt okay. But any combination of changing speed or direction immediately gave it away as an inauthentic experience. I wanted a slower swipe to result in a slower animation. I wanted the gesture to be cancellable in mid swipe if you changed your mind.

But I had other fish to fry, so I let it slide.

Along the way, I added left and right swipe recognizers to toggle between the slower 5-second increment for the circle gesture and the fast 1 minute increment. This was a great shortcut for me personally, but it wasn’t very discoverable and probably was getting triggered accidentally more often than I wanted to admit.

Between swiping in all four directions, a long press to bring up the circle, and one and two-finger tap gestures, it was getting to be a pretty complicated gesture landscape on that main screen. Something had to give. The more time passed, the more features I added to that screen, the more daunting the prospect of getting a pan gesture to behave exactly the way I wanted became.

Fast forward to a few years later, and I decided enough was enough. The next update was going to put an end to the madness.

So I replaced all four swipe gestures with a single pan gesture that recognizes the difference between horizontal and vertical swiping, tracks with your finger, and allows you to cancel the gesture mid-swipe if you don’t swipe past a certain threshold.

For vertical pans, once you hit the threshold, time gets added or subtracted. As a bonus, if you keep holding, it will keep adding or subtracting every half second until you let go. So you can add or subtract several minutes with one gesture.

The circle gesture is probably still the way to go for bigger changes to the timer, but for adding or subtracting one or two minutes at a time, panning works great. The gestures work whether the timer is running or not, of course.

While I was at it, I added some icons to the horizontal panning to show the customer what the gesture is about to do.[3] Now it’s clearer that this gesture will change the circle speed. In prior versions, you’d just get a message that the speed had changed after the fact.

As a final bit of fine-tuning, I added haptic feedback on compatible devices. And that really tied the room together. So much so that I added haptics to the circle gesture as well.[4] There’s just something so visceral about that little click under your finger when a gesture gets recognized.

Anyway, now that one of the longest-standing embarrassing reminders of my early-developer years is gone, I’ll have to find something else that irks me about Fin to fix next.

The point is, most of the time you’re thinking about using UISwipeGestureRecognizer, what you really want is a pan. 9 times out of 10, it’ll feel way better to the touch.

That’s not to say I should have done all this work the right way years ago, by the way. Sometimes punting on the tough stuff and getting the product out the door is absolutely the right thing to do. It’s just nice to be able to go back and smooth over some of those rough edges in an app—even if you haven’t gotten around to it for years.

  1. I hadn’t yet added the circle gesture for adding and subtracting time, either. The early versions of Fin were really limited. ↩︎

  2. Swipe gestures are super simple. Set the direction, and when UIKit detects the swipe, you get a method fired. But you only have that one data point: a successful swipe. Pans are far more capable, but also far more complicated for a newbie developer to manage, with distances traveled and velocities with which to contend. You get a lot more data than you usually need, and thus you have to learn to pick and choose which data are important and how best to react to them. ↩︎

  3. Full credit to the makers of Twitterrific for my animations here, as I stole the idea outright from them. The icon pans in from the side of the screen in grey, then lights up to the highlight color when it is “active.” Let go while it’s active, and the toggling of circle speed is performed. Swipe your finger back to make it inactive before letting go, and the action is cancelled. It’s one of those things that’s easier to show than describe. But Twitterrific uses it to great effect when swiping left or right on a Tweet. ↩︎

  4. I really wish iPad had the Taptic Engine. I realize that Force Touch is probably technically really challenging on a larger screen, but I hope Apple does manage to add it eventually. ↩︎