Custom background for UINavigationBar problems

半世苍凉 提交于 2019-11-30 05:32:21

Following the description from here, I suggest adding a category to the nav bar.

@implementation UINavigationBar (UINavigationBarCategory)

- (void)drawRect:(CGRect)rect {
    // Drawing code 
    UIImage *img = [UIImage imageNamed: @"navbar_background.png"];
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, CGRectMake(0, 0, 320, self.frame.size.height), img.CGImage);

}
@end

On iOS 5 this will not work but the good news is that there is a simple way of doing this

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"name"] forBarMetrics:UIBarMetricsDefault];

NOTE: This will only work on iOS 5 and above so make sure you check iOS version if you want to be backwards compatible.

rhdez

NavigationBar's subviews are constantly changing, i mean every view appear/disappear, so you shouldn't expect to have the added imageview at the index 0 of the subviews array.

You could try to add this at viewDidAppear (in every viewcontroller that manage navigation items /:):

NSLog(@"navbar's subviews before \n %@",[[[self navigationController] navigationBar] subviews]);

for (UIImageView *imgv in [[[self navigationController] navigationBar] subviews]) {
    [[[self navigationController] navigationBar] sendSubviewToBack:imgv];
}

NSLog(@"navbar's subviews after \n %@",[[[self navigationController] navigationBar] subviews]);

I have used Hauek's solution but when the bar has diferent flavor in other controllers, it could give some minor problems, anyway, this is neither the best option.

Hope it help, at least to understand why what you were doing wasn't working,

Instead of doing it in drawRect: you can override the drawLayer:inContext: method in a UINavigationBar category class. Inside the drawLayer:inContext: method, you can draw the background image you want to use. Also you can choose different images for portrait and landscape interface orientations if your app supports multiple interface orientations.

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
    if ([self isMemberOfClass:[UINavigationBar class]] == NO) {
        return;
    }

    UIImage *image = (self.frame.size.width > 320) ?
                        [UINavigationBar bgImageLandscape] : [UINavigationBar bgImagePortrait];
    CGContextClip(context);
    CGContextTranslateCTM(context, 0, image.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), image.CGImage);
}

This complete demo Xcode project on customizing the appearance of UINavigationBar might also be helpful.

The way you can simply add a new background to your UINavigationBar is next.

/////////
 UINavigationController *navController = [[UINavigationController alloc] init];
 UINavigationBar*bar=[navController navigationBar]; // get navigation bar 
  NSArray*barSubview=[bar subviews]; // get all subviews of bar
 UIView*backView=[arr objectAtIndex:0]; // at index 0 lying background view of our bar
 backView.alpha=0.0f;// set alpha to 0 and it will become invisible

    UIImageView*imgView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"top-bar.png"]];// create the image view that we will insers as subbview in our bar
    imgView.frame=CGRectMake(0, 0, 320, 44);
    [bar insertSubview:imgView atIndex:0];// and it will be out new background
    [imgView release];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!