iOS Programming 101: How to Customize Navigation Bar and Back Button
Previously, in our iOS Programming 101 series, we showed you how to customize the appearance of the Tab Bar. In this tutorial, we’ll continue to talk about UI customization and cover how to use Appearance API to make the Navigation Bar more beautiful.
Here are what you’ll learn in this tutorial:
- Customizing the View with background image
- Customizing UINavigationBar including background image and text style of title
- Customizing the appearance of UIBarButtonItem
As usual, we’re going to illustrate the concept by converting a plain navigation bar to one with customized graphics. However, to help you focus on learning the customization, we’ve prepared the Xcode project for you to start with. Before proceeding, first download the Xcode project here (note: the project is created using Xcode 4.5).
If you build and run the project, you’ll get an app with simple navigation UI. Now we’ll work together to style the navigation bar, customize the bar buttons and assign our own background image for the view.
Customizing the View Background
First, we would like to change the background of view controller with our own image. If you open the Xcode project, you’ll see a set of images that we’ve added for you. To set the background image, open the “RecipeViewController.m” and add the following line of code to the end of “viewDidLoad” method:
1 |
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"common_bg"]]; |
Apparently, you can use the “backgroundColor” property of the view to change the background color. What you may not know is that you can also use the same property to set the background image. The trick is to create a UIColor object using the “colorWithPatternImage”. During drawing, the image in the pattern color is tiled as necessary to cover the view area.
After the change, compile and run the app. It should like this:
Styling the UINavigationBar
Prior to iOS 5, developers can only change the style of navigation bar through a handful of properties. But the problem is the change only applies to the navigation bar of a specific view. From iOS 5 and onwards, the SDK allows developers to style the navigation bar by using Appearance API. You can easily customize the appearance of navigation bars throughout the app using the appearance proxy ([UINavigationBar appearance]).
Changing Navigation Bar Background
Open “AppDelegate.m” and add the following in the “application:didFinishLaunchingWithOptions” method:
1 2 3 4 5 6 7 |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UIImage *navBackgroundImage = [UIImage imageNamed:@"navbar_bg"]; [[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault]; return YES; } |
The first line of code creates the UIImage object with our own background image of navigation bar. Then we use the appearance proxy to assign the image.
Customizing the Title Text of Navigation Bar
Next, we’ll change the font style of the title text. You can customize the text style by using the “titleTextAttributes” properties of the navigation bar. You can specify the font, text color, text shadow color, and text shadow offset for the title in the text attributes dictionary, using the following text attribute keys:
- UITextAttributeFont – Key to the font
- UITextAttributeTextColor – Key to the text color
- UITextAttributeTextShadowColor – Key to the text shadow color
- UITextAttributeTextShadowOffset – Key to the offset used for the text shadow
In the “application:didFinishLaunchingWithOptions” method of AppDelegate.m, add the following code:
1 2 3 4 5 6 |
[[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys: [UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0], UITextAttributeTextColor, [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],UITextAttributeTextShadowColor, [NSValue valueWithUIOffset:UIOffsetMake(0, 1)], UITextAttributeTextShadowOffset, [UIFont fontWithName:@"HelveticaNeue-CondensedBlack" size:21.0], UITextAttributeFont, nil]]; |
The above code alters the text style of navigation bar title. We use the HelveticaNeue-CondensedBlack as the font type, set the color to white and add a shadow to the text.
Now compile and run the app again. This is what the customized navigation bar looks like:
Customizing the Appearance of UIBarButtonItem
Lastly, we’re going to change the appearance of back button, as well as, other navigation bar buttons (i.e. UIBarButtonItem). Again, open “AppDelegate.m” and add the following code in the “application:didFinishLaunchingWithOptions” method:
1 2 3 4 5 6 7 |
// Change the appearance of back button UIImage *backButtonImage = [[UIImage imageNamed:@"button_back"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 6)]; [[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; // Change the appearance of other navigation button UIImage *barButtonImage = [[UIImage imageNamed:@"button_normal"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 6, 0, 6)]; [[UIBarButtonItem appearance] setBackgroundImage:barButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; |
We first create the UIImage objects using our own images (i.e. button_back.png and button_normal.png) and then set the image object as the background image of the UIBarButtonItem. But what’s the resizableImageWithCapInsets: method for? The buttons in navigation bar are not in fixed size. It’ll be automatically resized depending on the text length of the button. For round rectangular button, you probably don’t want to stretch the button in all directions. So we use the resizableImageWithCapInsets: method to add cap insets to the image. During resizing of the image, areas covered by a cap are not resized. The below illustration will give you a better idea about the cap inset:
We define the cap inset using the UIEdgeInset structure. The UIEdgeInsets is structure that specifies float values for each cap inset: top, left, bottom and right areas of an image. For instance, line 1 of the above code instructs iOS that the left 13 pixels and the right 6 pixels of the back button image are not scaled or resized.
After making the code change, compile and run the app again. You should now have the custom back and edit buttons.
What’s Next
Hope you enjoy this tutorial! For your reference, you can download the final Xcode project here. The appearance proxy gives iOS developers a much easier way to customize the UI controls. You should utilize it to make your app more attractive. In later tutorials, we’ll show you how to style other UI components such as UITableView in iOS app.
As always, leave us comment if you have any questions about the tutorial.
Comments
Guntarion
AuthorSuper Awesome! Thank you verymuch for the tutorial.
Can’t wait for the tutorial of creating a custom UITableView design π
Simon Ng
AuthorThe new tutorial was just published.
http://104.131.120.244/ios-programming-customize-uitableview-storyboard/
Reza Rahmati
AuthorThank you for useful tutorials
I have a problem, I have changed the navagationbaritems background as you said, every thing is ok, but whenever I change the title of button (programatically) the background will be get back to it’s default.
I write the codes of changing the background in button action too, nothing is changed…
I’ll appreciate letting me know the solution.
Reza
Reza Rahmati
AuthorIs there any supportive one?
Sebastian Hennig
AuthorVery cool tutorial, thx for that π
Ewelina
AuthorLike always great tutorial π I love this site!
Simon Ng
AuthorGreat to hear that. Thanks!
Tenny
AuthorI think you have the best, easiest to follow xcode tutorials on the web! Every tutorial of yours is worth bookmarking! Great job and keep it up! Just wondering, are you a fulltime ios programmer? This blog is a side hobby?
Simon Ng
AuthorThanks for your kind words. It’s just my side hobby but hope one day it’ll turn into a full-time job π
The.Dude.In.Charge
AuthorDude, you are literarily the most awesome iOS tuts guy ever. I’ve been to raywenderlich, stack overflow & youtube and you left them all in your dust with this tutorial. Kudos.
Side hope: One day please do one on how you make your graphics assets π
Lonely Coder
AuthorReally helpful, would be even better if you had screenshots after every change you made to the display.
dina youssef
AuthorThat was a great help. Most tutorials had you create a UIButton and then adding it as custom view to the bar button item which worked with all bar button items except the back button. This worked quiet well. Thank you.
jjpp
Authorgood one
arash
AuthorSo nice!
Min
AuthorThanks for your help, but I still have a problem, how do I delete the text(Back) inside the button?
Krupit
Authorit’s very simple…..
write this code in your viewcontroller.m
– (IBAction)clearbutton:(id)sender
{
nametextbox.text==@””;
}
HtunLinAung
AuthorI have three nav background images and i want to change these images to nag bar of three views.
Can i do that or not?
Podster
AuthorIs there a way to set all UIBarButtonItem to plain style without borders? I tried below code but does not work…
[[UIBarButtonItem appearance] setStyle:UIBarButtonItemStylePlain];
Any ideas?
Salvatore
AuthorThis guide is working perfectly for me in portrait mode, but when in landscape mode, the back button is too lowered and is getting cut off by the underlying view(the bar button is working perfectly on the otherhand). I think it has to do with the values in the UIEdgeInsetsMake method, but i can’t get seem to find the optimal values.
Can anyone give me an hand?
Thank you
Salvatore
AuthorJust found the answer:
UIImage *backButtonImage = [[UIImage imageNamed:@”bar_button_back”] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 6)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
Bonnke
AuthorVery very very nice tutorials on this blog… Thanks a lot
eagle.dan
AuthorAwaiting new tutorial to fix button background issues on iOS7
ζζ°
Authorhi, according to the change of back buttons have a problem, if i want to keep the size of image, and hide the back button title, how to do that