Archive for September, 2010

Customizing the Look of UINavigationBar and UINavigationController

Saturday, September 11th, 2010

CustomNavBar.png I’ve recently worked on a number of iOS projects that require a custom background for the UINavigationBar including the navigation bar used by the UINavigationController. Customizing the look of a UINavigationBar is actually pretty simple. You can set the tintColor property to the color of your choice. But sometimes you need to do more. For example, say you want to have a title in your navigation bar that uses a font not available on iPad and iPhone. For this you will need to use an image to customize the navigation bar.

Let’s take a look at the various ways to customize the navigation bar.

The UINavigationBar has a style property called barStyle. barStyle can be set to UIBarStyleDefault or UIBarStyleBlack. The default uses a blue gradient background. When using UIBarStyleBlack you can also set the translucent property to YES to give the navigation bar a partially opaque look. If you are using Interface Builder, then you will set the Style property in the Inspector window. Here you have the option to style the navigation bar as Default, Black Opaque, and Black Translucent.

What if you want a color other than blue and black? You can set the tintColor property (aka Tint in IB) to any color you like. This changes the navigation bar’s color. Best of all, setting the tintColor will also change the background color used by the bar button items displayed within the navigation bar.

Sometimes, however, just changing the tint of the UINavigationBar isn’t enough. Sometimes you want to have a fancier background. Maybe the background you want has a different gradient style or lighting effect, or maybe you want a title displayed in the center of the navigation bar to use a font not available in iOS. How would you change the look of the navigation bar for these scenarios? Simple. You use an image that is drawn on the navigation bar.

There are two approaches you can use to draw an image on the navigation bar. You can create a new class that inherits from UINavigationBar and override the drawRect method. For example:

@interface KTNavigationBar : UINavigationBar {

}
@end

@implementation KTNavigationBar

- (void) drawRect:(CGRect)rect
{
   [super drawRect:rect];

   UIImage *image = [UIImage imageNamed: @"navbar.png"];
   [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}

@end

In this example, the image navbar.png is used to customize, or skin, the UINavigationBar. This is a nice, clean, object orientated way to customize the look of your navigation bar. The only thing you must remember to do is to use your custom UINavigationBar class within your application. This means changing the class type for those of us using IB.

Another trick you can use that doesn’t require changing the class type is to use a category. For example:

@interface UINavigationBar (KTCustomLook)

- (void) drawRect:(CGRect)rect;

@end

@implementation UINavigationBar (KTCustomLook)

- (void) drawRect:(CGRect)rect
{
   UIImage *image = [UIImage imageNamed: @"navbar.png"];
   [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}

@end

I admit I have used this approach in more than one project, but doesn’t feel right to me. It feels more like using voodoo or black magic then following good OO design. But this approach does work and it does save you time by eliminating the need to change the class type for each instance of UINavigationBar within your app. [Update: This approach doesn't feel right because it overrides a method in a category. You should know this is a bad, bad thing, and I don't encourage others to do it. That said, it does work.]

One thing to note when using an image to customize the UINavigationBar, you still want to set the tintColor for the navigation bar. As I mentioned, setting this property will also change the background color used by the bar button items. So you want to set the tintColor to the appropriate color making the button color fit in with the navigation bar color style.

For those of you who want to see these concepts in action, I posted a sample project, called CustomNavBar, on github. Enjoy.


Speaking at VTM and 360iDev This Fall

Friday, September 10th, 2010

Fall is almost here and it’s going to be a busy on for me. Not only will I be heads down trying to finish my upcoming book, I will be speaking at two iOS developer conferences. The first conference is Voices That Matter in Philadelphia on October 16 and 17. This will be my first VTM, and I’m very excited to be apart of the event. There are a lot of great talks planned for the 2-day conference. My talk will be on the advantages of writing universal apps for iPad and iPhone. Early bird pricing ends today so register now to save money. Use the discount code PHASPKR to save even more money.

The second conference I’m speaking at this fall is 360iDev Austin. It’s no secret that 360iDev is one of my favorite developer conferences. I have made numerous friends since attending my first 360iDev last year, and the networking I’ve done at past 360iDev conferences has help land me paying gigs. My session at 360iDev will be on the fundamentals of iPad programming. This session is intended for anyone just starting out with iPad programming. Earlier bird pricing as already ended for 360iDev Austin but even at the full price of $599, it is money well spent if you are serious about iOS programming.


My App Store Pricing Experiment: The Final Chapter

Wednesday, September 1st, 2010

Today is my final update on the pricing experiment I started back in May. You can read the previous posts here and here. The goal of the experiment was to see if the sales trend for Labor Mate would continue at the higher price of $1.99. After three full months, I can say the higher price has done more harm than good.

Labor Mate continues to bring in over $1K per month despite the higher price, but the trend doesn’t look good. Over the last few weeks, the number of sales has decreased everywhere except in Japan. For some reason, sales are up in Japan and if not for Japanese sales in August, Labor Mate would have posted it’s worse sales month in 6 months.

Since it’s inception date, revenue for Labor Mate has been on a slow but steady rise. The higher price has reversed that trend. Labor Mate now appears to be on a slow but steady fall. Not only that, Labor Mate, which at one time was in the Health and Fitness Top 100 category in App Stores throughout the world, is not longer visible on any Top 100 chart, anywhere. This three month pricing experiment maybe the start of a slow death for Labor Mate, but it’s not done for yet.

I have big plans in the works, and a new update is just around the corner. I was planning a big release in a few weeks that would hopefully justify the $1.99 price tag in the eyes of consumers but I’m changing my strategy. Starting today, Labor Mate is back down to 99 cents, and instead of a big update in a few weeks, I’m going to release 3 or 4 updates over the next 1 to 2 months. My goal here is to get Labor Mate back on track and return to the trend I was seeing before the price increase.

Update: One thing I should point out is Labor Mate has a lot of competition. The other similar apps cost between free and 99 cents. This maybe a key reason why a $1.99 Labor Mate cannot sustain the slow but steady growth seen by the 99 cent Labor Mate.