可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
回答1:
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
回答2:
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.
回答3:
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,
回答4:
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:
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];