如何在不使用drawRect类别的情况下将图像设置为导航栏背景?

时间:2011-09-08 13:22:14

标签: iphone ios ios4 uinavigationcontroller uinavigationbar

我想在iphone应用程序的导航栏上设置图像背景。大多数解决方案建议在类别中使用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

然而, Apple不推荐此。还有其他建议吗?

求助,

的Stephane

3 个答案:

答案 0 :(得分:4)

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

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

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

运行时类切换:

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

您还应该避免每次[UIImage imageNamed:...]使用drawRect:因为它可能会影响效果(动画效果)。将其缓存在ivar中:

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

(并以dealloc发布)

注意:由于iOS 5仍在NDA下,我不知道如何轻松添加背景图片。查看UINavigationBar的文档。

答案 1 :(得分:2)

经过测试的代码:100%正常工作

你的ViewDidLoad

中的

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

self.navigationItem.titleView = iv;

[iv release];

注意: urNavBarImage应与导航栏的大小完全相同。像这样你可以改变每个Viewcontroller导航栏。

答案 2 :(得分:1)

我为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];