Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom UINavigationBar Background

I've been trying to set up a custom background for the whole of my NavigationBar (not just the titleView) but have been struggling.

I found this thread

http://discussions.apple.com/thread.jspa?threadID=1649012&tstart=0

But am not sure how to implement the code snippet that is given. Is the code implemented as a new class? Also where do I instatiate the UINavigationController as I have an application built with the NavigationView template so it is not done in my root controller as per the example

like image 894
Anthony Main Avatar asked Apr 01 '09 08:04

Anthony Main


People also ask

How do I customize my navigation bar?

From Settings, tap Display, and then tap Navigation bar. Make sure Buttons is selected, and then you can choose your desired button setup at the bottom of the screen. Note: This option will also affect the location you swipe when using Swipe gestures.

How do I change the background color of a navigation bar in Swift?

navigationController. navigationBar. barTintColor = UIColor. newBlueColor() and of course this just changes the colour of the navigation bar of the view controller that the code is within.

Can you change the navigation bar on Iphone?

Change the Bar StyleA user changes the navigation bar's style, or UIBarStyle , by tapping the “Style” button to the left of the main page. This button opens an action sheet where users can change the background's appearance to default, black-opaque, or black- translucent.


4 Answers

Uddhav and leflaw are right. This code works nicely:

@interface CustomNavigationBar : UINavigationBar
@end

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

// this can go anywhere
+(UINavigationController*) myCustomNavigationController
{
  MyViewController *vc = [[[MyViewController alloc] init] autorelease];
  UINavigationController *nav = [[[NSBundle mainBundle] loadNibNamed:@"CustomNavigationController" owner:self options:nil] objectAtIndex:0];
  nav.viewControllers = [NSArray arrayWithObject:vc];
  return nav;
}

You have to create CustomNavigationController.xib and put a UINavigationController in it and change the navigationBar class to "CustomNavigationBar".

like image 92
EricS Avatar answered Oct 17 '22 09:10

EricS


You must use the 'appearance' proxy to change the background and other styling properties of controls such as UINavigationBar, UIToolBar etc. in iOS 5.xx. However, these are not available for iOS 4.xx so for backwards compatibility, you need a hybrid solution.

If you want to support both iOS 4.xx and iOS 5.xx devices (i.e. your DeploymentTarget is 4.xx), you must be careful in wrapping the call to the appearance proxy by checking at runtime if the 'appearance' selector is present or not.

You can do so by:

//Customize the look of the UINavBar for iOS5 devices
if ([[UINavigationBar class]respondsToSelector:@selector(appearance)]) {
    [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"NavigationBar.png"] forBarMetrics:UIBarMetricsDefault];
}

You should also leave the iOS 4.xx workaround that you may have implemented. If you have implemented the drawRect workaround for iOS 4.xx devices, as mentioned by @ludwigschubert, you should leave that in:

@implementation UINavigationBar (BackgroundImage)
//This overridden implementation will patch up the NavBar with a custom Image instead of the title
- (void)drawRect:(CGRect)rect {
     UIImage *image = [UIImage imageNamed: @"NavigationBar.png"];
     [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end

This will get the NavBar look the same in both iOS 4 and iOS 5 devices.

like image 22
bhavinb Avatar answered Oct 17 '22 09:10

bhavinb


You just have to overload drawRect like that :

@implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
    UIImage *image = [UIImage imageNamed: @"NavigationBar.png"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end
like image 29
Lithium Avatar answered Oct 17 '22 09:10

Lithium


Implementing a category is not advisable. iOS5 may provide relief for this issue. But for old APIs, you can -

  1. Subclass UINavigationBar to say CustomNavBar and implement the custom drawRect from Lithium's answer.
  2. For all IB based UINavigationControllers, provide CustomNavBar as custom class for their UINavigationBar.
  3. For all code based UINavigationControllers. Create a XIB with a UINavigationController and do step two. Then provide a factory method in code that loads the UINavigationController from the nib and provide an IBOutlet.

Eg.

[[NSBundle mainBundle] loadNibNamed:@"CustomNavigationController" owner:self options:nil];
UINavigationController *navController = self.customNavigationController;
navController.viewControllers = [NSArray arrayWithObject:controller]
like image 26
Uddhav Kambli Avatar answered Oct 17 '22 10:10

Uddhav Kambli