透明UINavigationBar下的自定义背景

时间:2010-02-08 06:33:39

标签: iphone uiimageview uinavigationbar

在“黑色半透明”UINavigationBar 下有一个自定义UIImageView,但我对结果不太满意。自定义图像不够清晰,当更改导航栏alpha值使其更加明显时,它会使导航栏标题和按钮不太明显。

问题:我想要一个完全可见的自定义UINavigationBar背景图片,其中包含完全可见的条形标题和按钮。任何想法我将如何得到所有这些?

更新:我的解决方案与这些答案类似,但有点不同。不想接受我自己的回答是正确的,所以在iLessons iLearned上发表了关于它的博客(link)。

5 个答案:

答案 0 :(得分:3)

我也想要一个自定义的UINavigationBar背景图片,最后通过以下方式解决它:

  • 在UINavigationController的初始化中,我创建了一个CALayer,其contents设置为背景图像,并相应地设置了框架。
  • 我将该图层添加到UINavigationBar的图层(在索引0处,在后台):[self.navigationBar.layer insertSublayer:imageLayer atIndex:0]

此时,它看起来还不错,但是如果你进行任何导航,标签和按钮就会消失在“背景”图层后面。所以,

  • 我创建了一个CALayer的子类,它改变了insertSublayer的行为:atIndex:这样就不会在背景层下插入任何图层。

像这样:

 @implementation CTNavigationBarLayer 
 - (void)insertSublayer:(CALayer *)layer atIndex:(unsigned)idx {
     if ( idx == 0 ) idx = 1;
     [super insertSublayer:layer atIndex:idx];
 }
 - (void)addBackgroundLayer:(CALayer*)layer {
     [super insertSublayer:layer atIndex:0];
 }
 @end
  • 在UINavigationBar上使用类别,我重复了+layerClass方法以返回[CTNavigationBar class],因此导航栏使用自定义图层。

当然,这会改变您应用中所有 UINavigationBars的行为,因此,如果这不是您想要的,那么您需要寻找其他方式。你可以继承UINavigationBar,但是在UINavigationController中使用该子类的唯一方法是通过IB(或者做一些相当有趣的mucking about来编程)

  • 最后,回到UINavigationController初始化,我用对我编写的addBackgroundLayer:方法的调用替换了层插入。

答案 1 :(得分:2)

在UINavigationBar的类别中使用drawRect在iOS5中不起作用。 Apple建议的方法是创建UINavigationBar的子类并在NIB文件中使用它。

答案 2 :(得分:2)

为了晚些时候来到这里的人们的利益,值得注意的是iOS5为这种定制提供直接支持。要更改UINavigationBar底层的图像,请使用

- (void)setBackgroundImage:(UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics

还有一个属性

@property(nonatomic, copy) NSDictionary *titleTextAttributes

用于调整标题。并且您可以使用外观代理在您的应用中普遍实现这些更改。在WWDC 2011,Session 114,“定制UIKit控件的外观”中进行了更多讨论。

在iOS5之前,你应该采用的方式是通过继承UINavigationBar。

答案 3 :(得分:1)

您还可以创建UINavigationBar类别类并覆盖 drawLayer:inContext:方法。在 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);
}

有关自定义UINavigationBar thisthis外观的完整演示Xcode项目可能会有所帮助。

答案 4 :(得分:0)

如果你有多个UINavigationController(例如在UITabBar中),因为它使用UINavigationBar类别,每个UINavigationBar需要不同的背景,那么ardalahmet解决方案不是正确的。