I wanted to write a bit about some of my UI design decisions, and some lessons I learned during the development process with regard to creating software interfaces for the iPhone. So here goes.
This post contains plenty of screenshots and a few brief movies too; screenshots are bordered in white, and movies are bordered in blue (with a Quicktime controller immediately below each one). You might not see the movies if you’re reading this via the feed instead of on the web.
Starting with what's familiar
As I described in my previous post, my concept for Favorites was a speed-dial utility that uses your contacts’ photos, and behaves a lot like the iPhone’s Home screen. I liked the visual metrics of the 4x4 layout (excluding the dock at the bottom), and the fact that every single iPhone owner has looked at that screen about a thousand times.
I took the basic Home screen layout and moved it downwards to leave room for a titlebar at the top. I also wanted some basic editing controls (a button to toggle Edit Mode, and a + button to add a new favorite), so I initially mocked those up in a toolbar at the bottom of the screen:
(Note: the above is a cut-up of screenshots of my Home screen, so don’t be alarmed at the duplicate app-icons.)
I also wanted to include some kind of dynamic help, though, and with the buttons at the bottom of the screen the entire titlebar (actually a navigation bar) along the top was a waste of space. I had a play with my iPhone and noted that add/edit controls tend to be along the top of the screen, so I moved the buttons into the titlebar and everything fell into place. The basic UI of Favorites was born:
Favorites can of course also display the photos without labels, which I personally prefer.
I’ve noticed that some of the other visual speed-dial apps on the store have a similar display but clearly don’t proportionately scale the images; they just draw them straight into the non-square area, resulting in a squashed appearance. I ported my NSImage cropping category to iPhone to make this easy; I’ll no doubt release it when possible.
In any case, the basic idea is that you can interact with each favorite in two ways: tap or double-tap. One of those performs your chosen default action (call, SMS or email - initially set to call), and the other shows the Overlay. Initially, a single tap performs the default action and a double-tap shows the Overlay.
I toyed with the idea of using tap-hold for the secondary action instead of double-tap, but I decided it would be potentially confusing for two main reasons:
- People are used to tap-hold meaning "enter edit mode" on the Home screen, so I'd be overloading a familiar interaction (in a familiar-looking environment, indeed) with a new meaning. That struck me as a bad idea.
- Tap-hold takes longer than double-tap (on average), and is an interaction which requires more effort. This is fine for a rare operation like rearranging your apps on the Home screen, but it's not ok for showing the Overlay, which is potentially a much more frequent action.
So, I went with tap and double-tap. This opened up the problem of double-tap being a more difficult interaction than a single tap (due to the twin constraints of having to tap twice in the same general area, and having to do so within a time-limit, before the second tap would simply register as a new single-tap).
I did some informal testing here and decided on a nominal double-tap interval of 0.4 seconds, and added a setting to allow any value between 0.2 and 1.0 seconds. Most people should find the default setting just fine, but it’s important to consider those who may have difficulty with rapid, precise movements.
Obviously, the longer you wait to see if a second tap is going to occur (and thus be considered a double-tap action), the longer you have to wait before the app can decide that you’ve only single-tapped. Thus, the less strict you are about the two taps of a double-tap happening in quick succession, the longer you need to wait after single-tapping before the single-tap action is triggered. So it’s a trade-off, and one that I felt was individual enough to actually warrant a setting (settings to be avoided in general, if at all possible - but basic accessibility allowances are a very good exception).
That brings us to the actual drag-rearranging which again mimics the Home screen.
This uses Core Animation to make the other favorites slide around to make room as you drag one; they move when the center-point of the dragged favorite enters the bounds of another; this gives a smooth and unsurprising behaviour which doesn’t feel unstable.
I initially tried moving the other favorites when any part of the dragged favorite overlapped another, but the result was a sense of the layout being too fluid and too eager to rearrange itself.
There’s one more subtlety to the drag-rearranging code which you may never notice, but which I took some extra time on. When your favorites are laid out, they all occupy a different depth-level, such that the later (further to the bottom-right) ones are “higher” (closer to the user) than the earlier ones. I decided on this model because the favorites are added from top-left to bottom-right as with apps on the Home screen, and it thus provides an unsurprising appearance when they’re rearranging themselves (with later ones flowing over the top of earlier ones).
This presented a problem when dragging, however. Dragging a favorite to a position further to the right and/or bottom than its current position would result in it being “behind” the favorite whose position it was about to occupy, and thus the dragged favorite would be temporarily partially obscured as the others reflowed. This was unintuitive, since we often think of a dragged object as not just dragged but sort of picked up out of its place, moved around and then put back down.
I addressed this by temporarily promoting the dragged favorite to be topmost during the drag, then when it’s released it will remain topmost as it animates into its final grid-aligned position before finally (and invisibly to the user) being restored to its proper new depth-order. This presents a sensible interaction model to the user, who will ideally never even notice what actually occurs.
One final point I wanted to note is that, during initial development of the favorites-adding code, I felt uncomfortable about how empty the screen was when you only had one or two favorites. Each favorite looked very tiny against the vast expanse of black, which was unpleasant. The solution was obvious: resize the favorites as you add and remove them, to best fill the available space.
Your favorites will display in a 2x2, 3x3 or 4x4 grid as appropriate, resizing and rearranging themselves as the layout changes. There was also briefly a 1x1 display, but it was quite alarming as one of the first things the new user sees after adding their first favorite, so I made 2x2 the minimum grid-size (with the largest possible size for each favorite). Also, the photos in the user’s Contacts database don’t fare well when resized up to fill most of the iPhone’s screen, so it wasn’t a big loss.
I tested the variable-sized grid layout and decided it worked well, even though it detracted somewhat from the idea of being like the Home screen. The one thing which still wasn’t quite right was the way that deleted favorites just winked out of existence; the feature needed some animation to provide visual confirmation and reassurance to the user that the deletion had gone as planned and nothing unexpected had occurred.
Thus, when you delete a favorite, it will temporarily drop to the lowest depth-level (this doesn’t affect its position on screen), and then drop away downwards behind the others, fading out of existence after a brief distance. It sounds elaborate but it occurs asynchronously and very quickly, and I think it’s a good visual cue. Hopefully you’ll agree.
Overthinking the Overlay
The next major part of Favorites is the Overlay, where you may spend a fair bit of time if you often alternate between calling, texting and emailing your favorite contacts. I didn’t have much of an idea how to approach the visual design of the Overlay until I happened to glance at the phone during a call - the Phone app presents an overlay which provides an ideal control layout. You can compare the two overlays below.
Reasonably similar, but with a few deliberate differences.
- Favorites darkens its overlay's background, since the grid of favorites provides a higher level of visual noise than the presumably more uniform wallpaper shown behind the call overlay. I didn't want the background to be solid black, but I did want to significantly push it into the background, to focus attention solely on the overlay's controls.
- The buttons at the bottom of my overlay are taller than the End Call button. I felt that this was appropriate since there are two buttons to interact with in the same vertical space, distinguished only by their horizontal positions. Also, given the usually almost vertical orientation of your finger when interacting with the device, and the potential for your finger slipping downwards during a touch operation, I decided that an enlarged vertical hit-area would never be unwelcome.
There are also a couple of other usability enhancements I’ve added to help the user interact with the overlay as easily as possible, which you can see in the next screenshot.
- The actual number or email address (and the label for that number/email) are shown when you tap on one of the three large action-buttons. This gives an extra memory-aid as to which actual values you assigned to those actions for this favorite. They're shown above the buttons, since displaying them below would cause them to be hidden by your hand.
- Each of the action-buttons highlights in a different colour, and tries to be as faithful to the standard iPhone colour-scheme as possible. The call button highlights in green since the Phone app icon is green. The email button highlights in blue. The SMS button presented an issue since that app's icon is the same green as the Phone app, and I thought that it would look awkward to have only the email button being a "different" colour, so I chose a third and somewhat intermediate lilac/purple colour for SMS.
The Overlay is a very simple piece of UI, but rest assured that plenty of thought and time has gone into it.
Buttons may (and should) be larger than they appear
Take a look again at the X-buttons (the delete buttons) attached to each favorite in the screenshot of Edit Mode a few paragraphs above. Go on, I’ll wait.
They’re enormous, aren’t they? Huge, hulking great black circles with a white X inside, just like in the Dashboard on Mac OS X. An easy target to hit, no matter how drunk you are.
Except they’re not huge at all. The iPhone screen is much smaller in real life than in screenshots of the simulator, and believe me - those buttons are tiny. In fact, they’re about one-sixth the size of the nail on my pinky finger, and I have pretty slender fingers. Think about that for a moment (the buttons, not my girl-hands).
I initially implemented those buttons just as you see them; they were as big as the actual icon they contained, and no more. And they were impossible to hit with any accuracy; I had to jab several times to actually trigger them. Completely unacceptable.
If you play with the apps on the Home screen, you’ll find it quite easy to hit the delete buttons, and yet they use exactly the same icon. The reason is that the virtual hit-area of the button is larger than it appears, and this is crucial in iPhone development. It’s why you haven’t really tested your UI until you’ve tested it on an actual device.
Accordingly, I enlarged the actual hit-area of my delete buttons, and voila - I could trigger them every time, without reducing the user’s ability to drag the favorites around. Behind the scenes, the actual active area of those buttons in Favorites looks like this:
Much better, and again invisible to the user - it just “works properly”. I’ll revisit this idea a little later.
It’s interesting to note that this idea of active areas differing from visible areas is found throughout the iPhone UI - specifically in most of the buttons. The standard button object has an interesting behaviour in the situation where you tap and hold, and then drag your finger off the button. On the desktop, when this happens the button would un-highlight as soon as your cursor left its visible boundary, and would highlight again if you moved the cursor back inside it again. Not quite so on iPhone.
The interesting thing is that the area in which you can tap to initially trigger the button is different from the area you must drag out of in order to cancel the operation - the latter is bigger! This applies to a large majority of all the buttons on the device. Here’s an illustration:
The yellow area is the area you can tap to trigger the button. If you tap and hold within that rectangle, the button will highlight. But if you drag your finger (still not having released the tap) out of the yellow area, the button will stay highlighted, and will still trigger if you then let go. It’s only when you drag outside of the green area that the button will return to its normal appearance, and no longer be triggered when you lift your finger.
My presumption is that Apple did some research and realised that slipping of the finger during a tap on a touchscreen device happens far more than slipping of the mouse-pointer during a click, and did the most logical thing they could: expand the active area once you’ve already tapped. Your own apps get this behaviour for free with standard button objects.
Pun definitely intended, but I mean touches in the sense of tweaks and finishing touches here, rather than the interaction. These were things which occurred to me during testing, and which are once again mostly invisible to the user, but which I wanted to mention here.
They all concern how Favorites determines which available display-names, phone numbers and email addresses to show, and how it behaves when you’ve just created a new favorite or changed the actual contact associated with a favorite.
- When you select a new contact for a fave, Favorites will use the contact's nickname as the default label, since it seems logical that you might have specified a nickname for someone you'd describe as a "favorite" contact. If there's no nickname (you can specify one in the Contacts app on iPhone or in Address Book on your Mac, you know), Favorites will use the contact's first name (or company's name).
- Since your iPhone is a mobile phone, Favorites will pre-select a phone number whose label is "mobile", regardless of case (or a localised variant thereof), as the call and SMS number for a favorite.
- On the presumption that people you regularly email will commonly tend to be work colleagues or business contacts, Favorites will pre-select an email address whose label is "work" as the email address for a Favorite.
- Favorites gets all its numbers etc from your Contacts database, so it's possible you'll choose a certain number for a favorite, then subsequently delete that number from the contact's card in Contacts. In this situation, Favorites will preserve the number you chose until you explicitly change it, since there isn't a completely predictable way to pick another number in that situation, and I felt that consistency would be a better choice. This applies similarly to labels for favorites.
These are tiny things, but when all put together they tend to increase the likelihood that Favorites will have done the Right Thing for the average user in a given situation, letting them get on with something more important than adding and configuring a list of favorite contacts.
An intensely textual experience
Favorites displays text all over its UI, and it’s always tempting to just accept the default behaviour of the standard non-editable text-fields on iPhone. However, I decided to put a little thought into the kinds of values which would be displayed in each location, and adopt different alignment, resizing and truncation behaviours as appropriate.
The majority of the static text in Favorites is shown in the favorite-editing UI, as shown below.
In order to mimic how Contacts and Address Book show such values, I split the numbers and email addresses into two actual fields: the label and the value. The labels are right-aligned, and the values are left-aligned, like a form. Everything is set to resize-to-fit (down to a legible minimum size).
The issue of long values is important too; how do you do line-breaking? My decision was that labels would truncate using an ellipsis at the end, but that numbers and email addresses would use an ellipsis in the middle - because the end of a number or email address is often just as important as the start (“is that the number ending in 55?”, or “is that his Gmail or Yahoo address?”).
When fields have scaled their text down to fit, they’re set to align the text-baseline (rather than center-line) with adjacent fields, in order to avoid an odd appearance of text floating upwards as it gets smaller. Definitely sweating the small stuff, but it does make a difference to the overall experience.
Pick a cell, any cell
A significant percentage of the total development time on Favorites was spent on the custom lists (grouped tables) you can see in the last few screenshots.
The entire thing is actually a reusable, customisable table view called MGOptionList, which goes to great lengths to make it very easy to let the user choose from a set of options, each with a name, optional extra label, represented value, optional icon, and optional editability.
A lot of the inspiration for these lists was how the option-lists in the Settings application behave.
Which spawns this list:
These lists introduce a concept which I wanted to make use of: the idea that colour indicates what is a value and what is a label. The values in the above screenshots are in a soft blue colour, whereas the labels (or unselected options) are black. I adapted this to create the blue/grey-on-black scheme seen in previous screenshots.
I had to create custom table-cell backgrounds for this, to allow the use of the rounded “sections” with a custom colour-scheme. I also had to reimplement the standard checkmark and right-arrow accessories in order to be able to specify their colours, but the end result was well worth it.
I also added the important (and explicitly Apple-recommended) visual cue of briefly highlighting and then immediately unhighlighting (with animation) a row after it’s tapped, as added confirmation to the user that their tap was received.
This meant creating some extra image resources, but gives a better user experience.
Regarding colour-schemes once again, my decision was that blue would mean “value” and that grey would mean “label”. This becomes particularly important when you consider that the following situation will often arise:
In the above screenshot,
- The contact has numbers available, but the user has chosen not to apply any number to the SMS function. Hence, "None" is shown in blue, with an arrow beside it to indicate that this is only one of several options, and can be changed.
- The contact however has no email addresses at all, thus "None" is shown in grey and without any arrow, to indicate that there's nothing to choose from.
You’ll find this model in place throughout Favorites. For example, the topmost part of the favorite-editing UI (where the actual contact associated with a favorite is chosen) shows the contact’s full name in blue and their photo with a blue border, since the contact is the actual “value” of that field.
Making it editable
This brings me to editability of options; i.e. not just picking an option from a list, but editing the actual option itself. This was important for allowing the user to enter a custom display-name (label) for a favorite. I did some mockups in Photoshop, and decided on this appearance:
The topmost option (which happens to be currently selected) is editable, as indicated by the arrow set apart from the rest of that row. Tapping anywhere on the row except the boxed arrow just selects that option as normal, adding a checkmark to it and making it blue. Tapping the boxed arrow area slides in an editing UI, shown below.
There are a few things to note about this:
- I decided to mimic the appearance of the option-cells for the actual editing field, to reinforce the idea that you're editing one of those options.
- I added a custom dark gradient behind the keyboard, instead of the default bright grey. I made use of the fact that the keyboard can be asked to display itself with a translucent black background, behind which a custom view can be shown.
- Both of the Done buttons (at the top-right, and in the keyboard) have the same function of accepting the current value and returning to the list. I kept the Done button in the top-right since it's consistent with the previous lists the user will have seen, and I didn't want to suddenly remove it just because the keyboard has one too.
The clear button within the field wasn’t there in my initial betas, but I quickly found that it was annoying to have to repeatedly tap the keyboard’s delete button to remove the default custom label (“Custom”). So, I added a clear button and immediately ran into the same issue as with the delete-buttons on favorites in Edit Mode - it was too small to hit!
It looks big enough in the screenshot, but take a look at the size of just the top section of my index finger (from the last joint to the tip) superimposed on that screen:
As I said before, I do not have huge mutant fingers; they’re actually kind of small - which makes the clear button ultra small. So, as before, the clear button’s active area is now considerably larger than its visual bounds, like so:
Lastly, the clear button and both Done buttons are suitably enabled and disabled as the user edits the text in the field; you can only clear the field or accept the value if some text actually exists. The Cancel button, however, is always enabled.
Because I care about this stuff, and I really care about how easy-to-use you find Favorites to be.
Providing help from the start
During development you’re often working with sample data from an early stage, and so it can actually be quite some time before you consider how your app will behave for a brand new user, upon first launch with no data at all.
My feeling was that offering help immediately, in the form of a tutorial, would be a good idea. Very few third-party apps on the iPhone offer built-in help, and it struck me that whilst Favorites is a simple concept, it couldn’t hurt to at least make the user immediately aware of where help could be found.
Accordingly, upon first launch you’ll see the screen below.
A bit plain, perhaps, but clear and no-nonsense. Of course, many people will just skip the tutorial and start exploring - and of course be confronted with a blank screen, utterly devoid of any favorites. I had initially planned to have an “import assistant”, allowing you to automatically make a set of favorites from your most-called or most-texted contacts, but iPhone firmware 2.1 blocked access to the relevant databases on the device so I had to abandon that idea.
To avoid just showing a blank screen, though, I added an additional visual cue which shows only if you have absolutely no favorites at all:
The help text at the bottom of the screen always show relevant help, of course, but I felt the blue call-out was appropriate in this situation, to help people get started - and it’s much more noticeable than the smaller dynamic help below.
The dynamic help is useful as a quick reminder of what you can do, or what will happen, in a given situation. For example, as you tap (and then perhaps tap again, for a double-tap) on a favorite, the help updates during the tap. Here’s what happens when I’ve tapped once on a favorite with my current settings:
and then when I immediately tap again:
You’ll also notice that the dynamic help is replicated in the titlebar during taps, since it’s more readily visible when your hand is over the screen. Also, note how the border of the favorite (including the badge-border, if a badge is shown) is visually highlighted during taps. Upon triggering an action, that border becomes blue.
Another place that help is available is in the About screen, accessible from the “i” button at the lower right of the main screen. The about screen looks like this:
There are two things to note here:
- There's a prominent "Tutorial" button, to trigger the tutorial at any time.
- The Favorites version-number is shown in a place which is very easy for the user to find if they need to report an issue - it's right under the star. The version number is of course dynamically determined from the app bundle, so it's always accurate.
The user can also force the tutorial to immediately be displayed the next time they launch Favorites by enabling that option in the Settings application.
So, help is never far away - which hopefully means that the user feels more confident and more capable using the software, which in turn hopefully means a happy customer.
This all seems like a heck of a lot of work for what’s essentially a simple speed-dial utility with some custom widgets, and that’s true - it is a lot of work. But it’s all worth it, because taken together all these minor points (some obvious, some not so obvious) contribute to a polished user experience, and a conscious or even subsconscious sense on the user’s part that the software just “gets” what thay want it to do.
That’s what user experience is about, and why it’s hard - because your software engineering or computing science degree is only a means to an end when solving the problem of how people want to interact with your software.
The ability to apply Human-Computer Interaction design principles to every stage of software development is a huge advantage in this age (and on these dual platforms - OS X and iPhone) of a beautiful and truly usable UI being expected rather than just “nice to have”. I relish that situation as a chance to improve my understanding of how people interact with computers, particularly this new touch-screen mobile platform we’re all so enthusiastic about.
I’ve enjoyed sharing my thoughts and my development process on Favorites with you, and I’d love to continue doing so in the future. If Favorites sounds like something you’d like to try out, head over to Instinctive Code to read more about it, or you can also go straight to Favorites on the App Store.
The fact of the matter is that interaction design considerations are completely interwoven through all of your code, and whilst it’s good practice to separate your Models, Views and Controllers, it is not good practice to design them in isolation from one another.
It’s no longer enough (if it ever has been) to be just a developer first and foremost. These days, try to be a software engineer and a UI designer as you create your applications - and get help with whichever aspect you feel less confident about. Your software will be an order of magnitude better for it.
Thanks for reading.