2011-10-28 61 views

回答

3

這是我在一個項目中使用的一種快速而骯髒的方式(我不需要支持橫向取向)。我用一個類別UINavigationBar實施它與方法swizzling。適用於iOS 4和5(我沒有在iOS 3上嘗試過)。

UINavigationBar的+ SYCustomBackground.h

#import <UIKit/UIKit.h> 

@interface UINavigationBar (SYCustomBackground) 
@property (nonatomic,retain) UIImage *sy_customBackgroundImage; 
@end 

UINavigationBar的+ SYCustomBackground.m

#import "UINavigationBar+SYCustomBackground.h" 
#import <objc/runtime.h> 

@implementation UINavigationBar (SYCustomBackground) 

static char BACKGROUND_IMAGE_KEY; 
static BOOL drawRectsSwizzled = NO; 

// Swizzles drawRect: and sy_drawRect: 
- (void)swizzleDrawRectIfNecessary 
{ 
    if (!drawRectsSwizzled) { 
     Method origMethod = class_getInstanceMethod([self class], @selector(drawRect:)); 
     Method myMethod = class_getInstanceMethod([self class], @selector(sy_drawRect:)); 
     method_exchangeImplementations(origMethod, myMethod); 
     drawRectsSwizzled = YES; 
    } 
} 

- (void)setSy_customBackgroundImage:(UIImage *)image 
{ 
    // iOS 5 
    if ([self respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) { 
     [self setBackgroundImage:image forBarMetrics:UIBarMetricsDefault]; 
    } 
    // iOS < 5 
    else { 
     [self swizzleDrawRectIfNecessary]; 
     objc_setAssociatedObject(self, &BACKGROUND_IMAGE_KEY, image, OBJC_ASSOCIATION_RETAIN); 
    } 
} 

- (UIImage *)sy_customBackgroundImage 
{ 
    // iOS 5 
    if ([self respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) { 
     return [self backgroundImageForBarMetrics:UIBarMetricsDefault]; 
    } 
    // iOS < 5 
    else { 
     [self swizzleDrawRectIfNecessary]; 
     return objc_getAssociatedObject(self, &BACKGROUND_IMAGE_KEY); 
    } 
} 

- (void)sy_drawRect:(CGRect)rect 
{ 
    UIImage *backgroundImage = self.sy_customBackgroundImage; 

    if (backgroundImage) { 
     [backgroundImage drawInRect:rect]; 
    } 
    else { 
     // No custom image, calling original drawRect: 
     // Note: it’s swizzled, so we must call sy_drawRect: 
     [self sy_drawRect:rect]; 
    } 
} 

@end 

然後你在viewWillAppear設置你的背景圖片,如果你想改變viewWillDisappear恢復它們圖像在一個UINavigationController

它並不完美,我想補充一些淡入淡出過渡,加推/流行音樂爲背景,但我沒有時間未定,可以隨意對其進行改進。

0

喜斯特凡·誇庫·,

試試這個它了作品......

UIImageView *bgNavigation= [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"bgNav.png"]];  
    self.navigationItem.titleView = bgNavigation;  
    [bgNavigation release]; 

在particularView`s willAppear方法

+0

'titleView'不適用於背景。 –

+0

我的意思是背景不是titleView :) – Steve

2

顯然,你已經知道如何將圖像設置爲導航欄的背景。

如果您需要區分各種視圖控制器,則需要更改應該表現不同的一個視圖控制器的viewWillAppearviewWillDisappear中的欄。你明白了。

6

這是爲導航控制器設置背景圖像的正確方法。這是在IOS 5

[navBar setBackgroundImage:[UIImage imageNamed: @"image.png"] forBarMetrics:UIBarMetricsDefault]; 
+0

如果你只想改變一個uiview背景,也許這不起作用。它適用於導航控制器的所有uview。 – giuseppe

+0

是的,這可能是大多數人的問題的解決方案,但是這個功能無法「解除」背景。 –

0

可我相信這是第一個實際的答案,這對於iOS5的,主要的問題是在背景圖像的「清除」一旦你完成。那麼,保留現有的。

@implementation MyViewController { 
    UIImage *_defaultImage; 
} 

- (void)viewWillAppear:(BOOL)animated { 
    _defaultImage = [self.navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault]; 
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"bar.png"] forBarMetrics:UIBarMetricsDefault]; 
} 

- (void)viewWillDisappear:(BOOL)animated { 
    [self.navigationController.navigationBar setBackgroundImage:_defaultImage forBarMetrics:UIBarMetricsDefault]; 
}