3

I'm using the category to customize nav bar. My code is:

- (void) drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColor(context, CGColorGetComponents([self.tintColor CGColor]));
    CGContextFillRect(context, rect);
}

It works well, but not in iOS 5. I need nav bar color to be solid without any gradient. How should I do this?

As I know, for iOS 5 the only way to replace drawRect method is to make a subclass, but is there any way to make all navigation controllers to use UINavigationBar subclass instead of original class?

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
Anton Filimonov
  • 1,655
  • 15
  • 19

3 Answers3

13

In iOS 5 you can use the UIAppearance protocol to set the appearance of all UINavigationBars in your app. Reference: link.

The way I got a solid color was to create a custom image for the navigation bar, and set it as UINavigationBars background. You might have to create the image with the same size as the UINavigationBar, at least that's what I did.

In your app delegate, do something like this:

UIImage *image = [UIImage imageNamed:@"navbarbg.png"];
[[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];

You also have to add the UIAppearanceContainer protocol to the header file:

@interface AppDelegate : UIResponder <UIApplicationDelegate, UIAppearanceContainer>

@end

You can probably achieve the same thing by setting some color or something, instead of an image. But I found this to be an easy solution.

matsr
  • 4,302
  • 3
  • 21
  • 36
  • Is this supposed to work with solid color? It does''t look like it works. – iJK Mar 27 '12 at 02:25
  • What do you mean by "solid color"? At least it works with `tintColor`. You can see in the header files of the UIKit framework which properties and methods that are supported by the `UIAppearance` protocol. The supported ones have `UI_APPEARANCE_PROTOCOL` written at the end of their line. Take the `UINavigationBar` as an example: it has 6 properties/methods that are supported. – matsr Mar 27 '12 at 04:00
  • I get a 2 px offset when I use this solution. It appears as a very thin black line at the top of the screen. How can I solve that? Otherwise this is a great answer since it doesn't rely on overriding navigation bar – Hgeg Oct 15 '12 at 13:37
  • 1
    @Hgeg, that sounds weird.. Are you using an image for the background? Check that the image has the same size as the navigation bar. – matsr Oct 15 '12 at 14:52
  • @matsr Yup. that was my problem. The image ratio was different from navbar size. Thanks for the help. – Hgeg Oct 16 '12 at 10:46
  • Instead of creating an actual image asset, you can create one programatically, as shown here: http://stackoverflow.com/a/1213816/883413 – Ric Santos Dec 28 '12 at 05:05
1

This covers both iOS 5 and iOS 4.3 and earlier

https://gist.github.com/1774444

0

This is more of a hack and has consistently worked for me. This needs to be in the AppDelegate file.

//Create  a size struct.
CGSize size = CGSizeMake(768, 50);

//CReate a imagecontext from a non-existing image. You can use a existing image as well, in that case the color will be the color of the image. 
UIImage *backgroundImage = [UIImage imageNamed:@"nonexist.png"];

UIGraphicsBeginImageContext(size);

[backgroundImage drawInRect:CGRectMake(0,0,size.width,size.height)];

UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

self.navigationController = [[UINavigationController alloc]initWithRootViewController:self.viewController];

Set the background color to be the color of your choice.

[self.navigationController.view setBackgroundColor:[UIColor blackColor]];

self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];

//Most important line.
[navigationController.navigationBar setBackgroundImage: newImage forBarMetrics:UIBarMetricsDefault];
WrightsCS
  • 50,551
  • 22
  • 134
  • 186
zyzzyxx
  • 323
  • 2
  • 9