如何在应用程序的各处设置导航栏的图像

时间:2012-10-18 19:45:31

标签: objective-c ios navigation storyboard

我正在使用故事板构建应用程序。现在我想在我的应用程序的每个屏幕上使用相同的topBar /导航栏。我想在此导航栏上设置图像。经过一番搜索,我发现了这段代码。

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

我把它放在我的appdelagate.M文件中的实现之上。但它没有用。 也有人知道这是否也适用于IOS 5.1?

亲切的问候。

2 个答案:

答案 0 :(得分:4)

看看UIAppearance。它允许您更改整个UI类的属性。例如,我在一个应用程序中有这个:

UIImage *img = [UIImage imageNamed: @"NavBarBackground.png"];
[[UINavigationBar appearance] setBackgroundImage:img forBarMetrics:UIBarMetricsDefault];
在iOS 5中引入了

UIAppearance。执行此操作的“旧”方法是使用相关类的类别(例如-drawRect:)覆盖UINavigationBar,就像您所做的那样。 (“Swizzling” - 交换你的方法用于SDK提供的方法 - 顺便说一句,不是必需的。)

我发现,当iOS5出现时,drawRect技巧不起作用,所以我必须有条件地使用UIAppearance将上述代码包含在if语句中:

if ([[UINavigationBar class] respondsToSelector:@selector(appearance)]) {
    ...
}

为什么有条件?我们继续支持iOS4,因此如果我们没有条件化这个UIAppearance内容,iOS4用户会遇到崩溃。所以,我们在应用程序中同时拥有了这个和drawRect解决方案!

如果你不需要支持iOS4,你一定要考虑UIAppearance来实现你的目标。

答案 1 :(得分:0)

我曾经为此目的调整drawRect,你可以使用+initialize(runtime.h)在method_exchangeImplementations执行调配。现在棘手的部分是调用原始的drawRect,因为方法被调整,你需要使用自定义绘图方法name来调用原始方法。就像你使用绘图一样,最后会有[super customDrawRect:rect];

- (void)customDrawRect:(CGRect)rect { 

   ... 
   [super customDrawRect:rect];
}

#import <objc/runtime.h> 

@implementation UINavigationBar (CustomImage)

+ (void)initialize {

    Method originalDrawRectMethod = class_getInstanceMethod([self class], @selector(drawRect:));
    Method customDrawRectMethod = class_getInstanceMethod([self class], @selector(customDrawRect:));
    method_exchangeImplementations(originalDrawRectMethod, customDrawRectMethod);
}



- (void)customDrawRect:(CGRect)rect {

    UIImage *image = [UIImage imageNamed: @"topbar.jpg"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];

    // original drawRect call
    [self customDrawRect:rect];
}


@end