UINavigationBar 问题的自定义背景
Posted
技术标签:
【中文标题】UINavigationBar 问题的自定义背景【英文标题】:Custom background for UINavigationBar problems 【发布时间】:2009-09-16 12:14:57 【问题描述】:我已经设法通过使用以下方法向导航栏添加自定义背景:
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UINavigationBar.png"]];
[myViewController.navigationBar insertSubview:iv atIndex:0];
[iv release];
这很好用,我可以看到标题和按钮。但是,当我向下钻取一层然后返回根目录时,按钮被隐藏,但标题仍然可见。似乎导航栏图像覆盖了按钮项。
我很困惑,因为我将它插入底部,所以我会假设当导航项被推送和弹出时,它们显示在导航栏中的其他视图之上。
有什么想法吗?
谢谢,
迈克
【问题讨论】:
【参考方案1】:根据here 的描述,我建议在导航栏中添加一个类别。
@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
【讨论】:
谢谢!它正在工作,只是导航栏似乎在图像顶部添加了从暗到亮的渐变!有什么办法可以消除这种影响? 实际上,它似乎正在将 PNG 颠倒过来!?有什么想法吗? 啊知道了...你需要使用 [img drawInRect:CGRectMake(0, 0, 320, self.frame.size.height)];而不是 CGContextDrawImage()! 您可以将上述代码添加到您的 appdelegate.m 文件的底部。之所以提到这一点,是因为我没有通过谷歌搜索得到这个。 @Michael Waterfall [img drawInRect:rect];【参考方案2】:在 ios 5 上这不起作用,但好消息是有一种简单的方法可以做到这一点
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"name"] forBarMetrics:UIBarMetricsDefault];
注意:这仅适用于 iOS 5 及更高版本,因此如果您想向后兼容,请确保检查 iOS 版本。
【讨论】:
【参考方案3】:NavigationBar 的子视图在不断变化,我的意思是每个视图都会出现/消失,因此您不应期望在子视图数组的索引 0 处添加图像视图。
您可以尝试在 viewDidAppear 中添加它(在每个管理导航项 /: 的视图控制器中):
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]);
我使用了Hauek's 解决方案,但是当酒吧在其他控制器中具有不同的风格时,它可能会出现一些小问题,无论如何,这都不是最好的选择。
希望它有所帮助,至少可以了解您所做的事情为什么不起作用,
【讨论】:
【参考方案4】:您可以覆盖 UINavigationBar 类别类中的 drawLayer:inContext: 方法,而不是在 drawRect: 中执行此操作。在 drawLayer:inContext: 方法中,您可以绘制您想要使用的背景图像。如果您的应用支持多种界面方向,您还可以为纵向和横向界面方向选择不同的图像。
- (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 关于自定义 UINavigationBar 的外观也可能会有所帮助。
【讨论】:
【参考方案5】:接下来是向 UINavigationBar 添加新背景的方法。
/////////
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];
【讨论】:
以上是关于UINavigationBar 问题的自定义背景的主要内容,如果未能解决你的问题,请参考以下文章
iPhone - 如何使用我的纹理背景自定义 UINavigationBar 后退按钮
使用 UINavigationController 默认 UIToolbar 的自定义背景
iPad 上 UIPopoverController 中 UIActionSheet 的自定义背景
删除 MFMailComposer 和 MFMessageComposer 的自定义 UINavigationBar
rightBarButtonItem.enabled 从 uinavigationbar 中删除我的自定义层
UINavigationBar setItems/pushNavigationItem/popNavigationItem 的自定义动画?