自定义UINavigationBar背景

Ant*_*ain 50 iphone objective-c

我一直在尝试为整个NavigationBar(不仅仅是titleView)设置自定义背景,但一直在努力.

我找到了这个帖子

http://discussions.apple.com/thread.jspa?threadID=1649012&tstart=0

但我不确定如何实现给出的代码片段.代码是作为新类实现的吗?另外我在哪里实例化,UINavigationController因为我有一个使用NavigationView模板构建的应用程序,所以它不是在我的根控制器中根据示例完成的

Eri*_*icS 44

Uddhav和leflaw是对的.这段代码很好用:

@interface CustomNavigationBar : UINavigationBar
@end

@implementation CustomNavigationBar
-(void) drawRect:(CGRect)rect 
{
    UIImage *image = [UIImage imageNamed: @"myNavBarImage"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end

// this can go anywhere
+(UINavigationController*) myCustomNavigationController
{
  MyViewController *vc = [[[MyViewController alloc] init] autorelease];
  UINavigationController *nav = [[[NSBundle mainBundle] loadNibNamed:@"CustomNavigationController" owner:self options:nil] objectAtIndex:0];
  nav.viewControllers = [NSArray arrayWithObject:vc];
  return nav;
}
Run Code Online (Sandbox Code Playgroud)

您必须创建CustomNavigationController.xib并在其中放置U​​INavigationController并将navigationBar类更改为"CustomNavigationBar".


bha*_*inb 31

您必须使用"外观"代理来改变控件的背景和其他样式属性,如UINavigationBar,UIToolBar等iOS中5.xx. 但是,这些不适用于iOS 4.xx,因此为了向后兼容,您需要一个混合解决方案.

如果你想同时支持iOS 4.xx和iOS 5.xx设备(即你的DeploymentTarget是4.xx),你必须小心将调用包装到外观代理,方法是在运行时检查是否存在'外观'选择器或不.

你可以这样做:

//Customize the look of the UINavBar for iOS5 devices
if ([[UINavigationBar class]respondsToSelector:@selector(appearance)]) {
    [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"NavigationBar.png"] forBarMetrics:UIBarMetricsDefault];
}
Run Code Online (Sandbox Code Playgroud)

您还应该保留可能已实施的iOS 4.xx解决方法.如果您已经实现了drawRectiOS 4.xx设备的解决方法,如@ludwigschubert所述,您应该将其保留在:

@implementation UINavigationBar (BackgroundImage)
//This overridden implementation will patch up the NavBar with a custom Image instead of the title
- (void)drawRect:(CGRect)rect {
     UIImage *image = [UIImage imageNamed: @"NavigationBar.png"];
     [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end
Run Code Online (Sandbox Code Playgroud)

这将NavBar在iOS 4和iOS 5设备中看起来相同.


小智 29

你只需要像这样重载drawRect:

@implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
    UIImage *image = [UIImage imageNamed: @"NavigationBar.png"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end
Run Code Online (Sandbox Code Playgroud)

  • Apple特别推荐这种技术.您应该继承UINavigationBar并重载drawRect.然后在您的XIB中将您的子类指定为UINavigationBar的类. (38认同)
  • 看起来这个方法在iOS 5中被打破了. (17认同)
  • 使用类别的覆盖方法不是一个好主意.在运行时,未定义将使用哪个版本的实现. (5认同)
  • 在我使用MPMoviePlayerViewController之前,这对我很有用.显然他们使用了一个子类UINavigationBar,所以我的自定义栏就显示出来了.我不得不使用@ ardalahmet的[下面的方法](http://stackoverflow.com/questions/704558/custom-uinavigationbar-background/4983492#4983492),但如果它不是`UINavigationBar`,则添加了对`super`的调用`isMemberOfClass:[UINavigationBar class]` (3认同)

小智 26

不建议实施类别.iOS5可以解决这个问题.但是对于旧的API,你可以 -

  1. 从Lithium的答案中UINavigationBar说出CustomNavBar并实现自定义drawRect的子类.
  2. 对于所有基于IB的UINavigationControllers,提供CustomNavBar他们的自定义类UINavigationBar.
  3. 对于所有基于代码UINavigationControllers.使用a创建一个XIB UINavigationController并执行第二步.然后在代码中提供一个工厂方法,UINavigationController从nib 加载并提供IBOutlet.

例如.

[[NSBundle mainBundle] loadNibNamed:@"CustomNavigationController" owner:self options:nil];
UINavigationController *navController = self.customNavigationController;
navController.viewControllers = [NSArray arrayWithObject:controller]
Run Code Online (Sandbox Code Playgroud)


Ahm*_*dal 10

您还可以覆盖类别类中的drawLayer:inContext:方法UINavigationBar.在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);
}
Run Code Online (Sandbox Code Playgroud)

而作为定制外观的完整演示Xcode项目UINavigationBar 可能会有帮助.