Tuesday, June 22, 2010

Iphone - The user is always right

After some amazing designer time and some scrambling to get all the UI changes in we got to let a bunch of people play with the app on actual devices, the feed back was awesome! As in extremely useful awesome.

Nothing beats first hand feedback!

Here's a few of the fun things we discovered we had to get right:

1. If the app does not respond to user touch as expected by the user, there will be confusion!

One of our views had editable text fields. Tapping a field would bring up the key pad but there was no cursor indicating that the specific text field was selected and typing would allow you to enter a value.

Result: "The app is broken!", "Um its not working?".

The funny thing is that if you had started typing you would see the values being entered, and it would work, but the lack of a prompt from the text field was enough to cause confusion. Needless to say this important issue has been fixed.

2. Very detailed views will be expected to be zoom-able.

Several of our views contain graphs, these occupy about half the full screen size. These graphs contained points and grids and axes so users would automatically try to zoom into them. Unfortunately, we had not yet put this functionality in. Currently this is a to do item on our list, but it is obvious that our users will expect this functionality, and will be disappointed if its not there.

3. Universal hatred for pop-up warnings about invalid entries.

If a user entered an invalid value, we were displaying pop-up warning messages that would tell you the valid range to use. Almost everyone who tried out the app and got a warning message automatically hated the message. Somehow it would create frustration, even when we thought we were being helpful. I guess the pop-up warnings make a user feel like they've done something really wrong and its broken while all they want is for the d#$# thing to work! We have replaced this with the more user friendly way of indicating invalid values, where a tiny red message is displayed under the text field.

4. Saving should succeed even when not all fields are complete.

If in the users mind, the information they are filling doesn't all need to be specified, then saving should work as long as some required fields have values. This allows the user to enter in the information they have in the moment and still continue using the app, and fill the rest later. Not being able to save what they have entered already discourages them from continuing to use the app or even returning to it later. So be very careful about what and how many fields are marked as required fields.

5. Respond to device orientation change.

While users didn't try or expect this with all our views, there did seem to be an expectation for the app to support this on the graph views. They expected the graph to be zoomed in and centered on device orientation change with all other elements not getting screen space. Returning to the original orientation should then return the user to the screen with the smaller graph and the rest of the view elements. Again a to do item which would be cool to have.

Well, now we all know when making other apps of some expectations and behaviors to keep in mind to ensure a wonderful user experience!

Wednesday, June 16, 2010

Iphone - The WOW factor

About a few weeks ago our little project got lucky, and received some designer time! Our design hero put together some screen shots at first, and then sent us the images and specifications that we would need. It was amazing how polished our application started to look as soon as we started to add in the changes! We were completely WOWED with the end result! See for yourself:

Images of Main Screen Before.

Images of Main Screen After.

Now a few discoveries about adding background images, specifying table and cell backgrounds, separators and text formatting.

1. Image as background

You can use an image as the background for a UIView by adding the following code in the view controller's viewDidLoad:

self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"imgname.png"]];

colorWithPatternImage is a really powerful method and can be used to set images as colors for tables, cells, labels etc.

2. Specify a color not available in the interface builder

The interface builder comes with a small selection of colors (you can add more libraries though), if you don't find the color you want, you can specify any color pro-grammatically using the UIColor class. The following example uses the color #DB3F61, and calls colorWithRed, which takes in the Red, Green, Blue and alpha values. The RGB values for #DB3F61 are RGB(219,63,97), each value is divided by 255 in order to use colorWithRed:

[UIColor colorWithRed:219.0f/255.0f green:63.0f/255.0f blue:97.0f/255.0f alpha:1.0f];

You can assign this UIColor to backgrounds, and separators etc. In the following code I've applied it to the separator line defined for tables.

self.table.separatorColor = [UIColor colorWithRed:219.0f/255.0f green:63.0f/255.0f blue:97.0f/255.0f alpha:1.0f];

3. Programmatic formatting of text

If you are creating textual elements on the fly and need the text to be formatted like the rest of the application, you can do it! Below is the example of a label, with text color, shadow size and font specified. Notice that the background color for the label is set to clearColor, this is a predefined color in the UIColor class. The shadow of the text is set to whiteColor. Other defined colors are red, orange, brown etc. The color of the label text is set to color #663300 (RGB(102,51,0)), using the colorWithRed method.

CGRect frame = CGRectMake(0, 0, 400, 44);
UILabel *label = [[[UILabel alloc] initWithFrame:frame] autorelease];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:20.0];
label.text = @"This is a label";
label.shadowColor = [UIColor whiteColor];
label.textAlignment = UITextAlignmentCenter;
label.shadowOffset = CGSizeMake(0,1);
label.textColor = [UIColor colorWithRed:102.0f/255.0f green:51.0f/255.0f blue:0.0f/255.0f alpha:1.0f];

4. Grouped tables, selected row issue

When using a UITableView, and setting the style to Grouped. You'll notice that when the top or bottom cell is selected, the grey or blue is outside of the rounded corners. Also the separators disappear for any selected cell. The workaround
for this issue is to always set the cell's background color for selected and unselected. In the view controller make sure you have a reference to the cell and in the viewDidLoad add the following code:

self.myCell.backgroundColor = [UIColor colorWithRed:219.0f/255.0f green:63.0f/255.0f blue:97.0f/255.0f alpha:1.0f];

This will set the cell's regular color. Now for selected cell color use the table's didSelectRowAtIndexPath, and for the selected row set the cell's background to a different color using the same code as above. Remember to set all the other cells back to regular cell color, and for each cell in the interface builder set the Selection property to none.