如何将图像设置为导航栏背景而不使用drawRect类别?

问题描述:

我想设置一个图像背景到我的iPhone应用程序的导航栏。大多数解决方案建议在一个类别使用的drawRect,如:如何将图像设置为导航栏背景而不使用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 

然而,苹果不推荐这种。任何其他建议?

THX帮助,

斯特凡

Apple强烈建议我们使用子类而不是类别(WWDC 2011,Session 123)。

创建一个实现了drawRect:方法的子类和类的导航栏设置为自定义类:

  • ,如果你在Interface Builder工作,在检查更改类
  • 如果你创建一个独立的导航栏(没有导航控制器),例化你的自定义类
  • 如果以编程方式创建导航控制器,则可以利用ObjC运行时。在运行时

类交换机:

#import <objc/runtime.h> 
... 
object_setClass(theNavController.navigationBar, [CustomNavigationBar class]); 

你也应该避免在drawRect:每次使用[UIImage imageNamed:...],因为它可能会对性能产生影响(动画)。它缓存在伊娃:

if (!bgImage) { 
    bgImage = [[UIImage imageNamed:@"NavigationBar.png"] retain]; 
} 
[bgImage drawInRect:...]; 

(在dealloc中释放)

注:随着iOS 5的仍然是保密协议,我不能提你怎么能轻松地添加背景图片。查看UINavigationBar的文档。

+0

的iOS5的新API不缩放图像。 :-( –

+0

@Seymour是的,我也注意到了,我用的是320 * 44的图片,我可能会提交一个功能请求 – Jilouc

+0

你可以在设置之前将UIImage的大小调整为navigationBar的大小 - 适用于我这样 –

测试的代码:100%工作

在乌尔viewDidLoad中

UIImageView *iv=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"urNavBarImage.png"]]; 

self.navigationItem.titleView = iv; 

[iv release]; 

注:urNavBarImage应的确切大小导航栏。像这样你可以改变每个ViewController导航栏。

我已经创建了一个UINavigationBar的自定义类别如下

UINavigationBar+CustomImage.h 

#import <UIKit/UIKit.h> 

@interface UINavigationBar (CustomImage) 
    - (void) setBackgroundImage:(UIImage*)image; 
    - (void) clearBackgroundImage; 
    - (void) removeIfImage:(id)sender; 
@end 

UINavigationBar+CustomImage.m 

#import "UINavigationBar+CustomImage.h" 

@implementation UINavigationBar (CustomImage) 

- (void) setBackgroundImage:(UIImage*)image { 
    if (image == NULL) return; 
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 
    imageView.frame = CGRectMake(110,5,100,30); 
    [self addSubview:imageView]; 
    [imageView release]; 
} 

- (void) clearBackgroundImage { 
    NSArray *subviews = [self subviews]; 
    for (int i=0; i<[subviews count]; i++) { 
     if ([[subviews objectAtIndex:i] isMemberOfClass:[UIImageView class]]) { 
     [[subviews objectAtIndex:i] removeFromSuperview]; 
    } 
    }  
} 

@end 

我调用它从我的UINavigationController

[[navController navigationBar] performSelectorInBackground:@selector(setBackgroundImage:) withObject:image];