Custom background for UINavigationBar problems

2019-02-04 03:41发布

I've managed to add a custom background to my navigation bar by using:

UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UINavigationBar.png"]];
[myViewController.navigationBar insertSubview:iv atIndex:0];
[iv release];

This works fine and I can see the title and buttons okay. However, when I drill down one level and then go back to the root, the buttons are hidden, but the title is still visible. It appears the navigation bar image is covering the button items.

I'm confused as I'm inserting it at the bottom so I would assume when the navigation items are pushed and popped that they are displayed above other views in the navigation bar.

Any ideas?

Thanks,

Mike

5条回答
地球回转人心会变
2楼-- · 2019-02-04 03:49

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,

查看更多
太酷不给撩
3楼-- · 2019-02-04 03:53

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];
查看更多
干净又极端
4楼-- · 2019-02-04 03:55

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.

查看更多
5楼-- · 2019-02-04 04:00

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
查看更多
淡お忘
6楼-- · 2019-02-04 04:07

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.

查看更多
登录 后发表回答