2012-01-19 44 views
2

我有一個問題,要更改IOS版本的UINavigationBar的背景圖像< 5.我已經讀過一個很好的解決方案,它基於方法調整,但這個問題解決方案是當我添加它涵蓋的圖像時,所有內容都包括導航欄上的按鈕。 我發現這部分的工作對我來說是在下面的代碼基礎的解決方案:在iOS中更改UINavigationBar的背景圖像<5

@interface UINavigationBar (UINavigationBarCategory) 
-(void)setBackgroundImage:(UIImage*)image withTag:(NSInteger)bgTag; 
-(void)resetBackground:(NSInteger)bgTag; 
@end 

@implementation UINavigationBar (UINavigationBarCategory) 

-(void)setBackgroundImage:(UIImage*)image withTag:(NSInteger)bgTag{ 
if(image == NULL){ //might be called with NULL argument 
    return; 
} 
UIImageView *aTabBarBackground = [[UIImageView alloc]initWithImage:image]; 
aTabBarBackground.frame = CGRectMake(0,0,self.frame.size.width,self.frame.size.height); 
aTabBarBackground.tag = bgTag; 
[self addSubview:aTabBarBackground]; 
//[self sendSubviewToBack:aTabBarBackground]; 
[aTabBarBackground release]; 
} 
-(void)setRightButton:(UIButton*)button withTag:(NSInteger)bgTag{ 
if(button == NULL){ //might be called with NULL argument 
    return; 
} 
    [self addSubview:button]; 
} 

/* input: The tag you chose to identify the view */ 
-(void)resetBackground:(NSInteger)bgTag { 
[self sendSubviewToBack:[self viewWithTag:bgTag]]; 
} 
@end 

我用這個類別中我ViewWillAppear方法是這樣的:

-(void) viewWillAppear:(BOOL)animated { 
UIImage *backgroundImage = [UIImage imageNamed:@"background_confernce_import_logo"]; 

if ([self.navigationController.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) 
{ 
    [self.navigationController.navigationBar setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault]; 
} 
else{ 

    [[self.navigationController navigationBar] setBackgroundImage:backgroundImage  withTag:8675309]; 
} 
} 

在else子句我打電話setBackgroundImage。沒問題,但問題是,如果我在頁面1的導航欄上有一個右鍵,並在回到第1頁後轉到第2頁,則該按鈕將消失。我應該在我的應用程序的每個頁面中更改導航欄的背景圖像,如viewWillAppear方法中放置新圖像的方法。 任何幫助將不勝感激。在IOS 5下不存在這樣的問題,但它應該可以在兩個版本上運行。

+0

[自定義背景UINavigationBar的(http://stackoverflow.com/questions/704558/custom-uinavigationbar-background) – Till

+0

@Till的可能重複,答案可能是幾乎相同(爲紐帶您發佈)但問題稍有不同,因爲它詢問了實施自定義背景的具體嘗試...... – sergio

+0

@sergio公平不夠 - 有道理。 – Till

回答

1

我討厭這麼說,但是你的方法(添加一個子視圖來保存背景)並不會完全因爲你提到的原因。每次導航欄重新繪製時,子視圖都不會保留其z順序(因此它將覆蓋其他UI元素)。此行爲是由其他來源(見this,例如)

描述如果你不想使用混寫,你可以在一個類別覆蓋drawRect,使背景總是正確繪製。 (這最後一個選項的缺點是,應用程序中的任何導航欄將以相同的背景繪製)。這是一個示例代碼我使用:

@implementation UINavigationBar (CustomBackground) 

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

一種不同的方法可以是:

  1. 子類UINavigationBar;
  2. 重寫drawRect;
  3. 在Interface Builder中,將導航欄對象的類設置爲您的UINavigationBar子類。

我還沒有嘗試過,但它應該工作。

+1

調整方法已成爲NoNo - 如果您這樣做,Apple會拒絕您的應用程序。 – Till

+0

此解決方案爲每個導航欄只設置一個圖像我需要爲每個頁面使用不同的圖像。正如你在最後一行中提到的那樣。我看到塞巴斯蒂安塞利斯的方法調整代碼,但它的油漆都包括我想要在導航欄中的按鈕完好無損的按鈕。 –

+0

@Till:謝謝,我不知道它... – sergio

0

按照要求,這裏來了我的調皮,沒有真正拋光的黑客。這真的只是爲了讓OP開心。 Sergio給出了正確的答案。


UINavigationBar的+ CustomDraw.m

NSString *gNavbarBackgroundImageName = @"default_navbar_background.png"; 

@implementation UINavigationBar (CustomBackground) 

- (void)drawRect:(CGRect)rect 
{ 
    if (gNavbarBackgroundImageName != nil) 
    { 
     UIImage *image = [UIImage imageNamed:gNavbarBackgroundImageName]; 
     [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 
    } 
} 
@end 

UINavigationBar的+ CustomDraw.h

extern NSString *gNavbarBackgroundImageName; 

這裏是兩個視圖控制器中的示例用法...


FooViewController.m

#import "UINavigationBar+CustomDraw.h" 

@implementation FooViewController 

- (void)viewWillAppear:(BOOL)animated 
{ 
    gNavbarBackgroundImageName = @"foo_navbar_background.png"; 
    [self.navigationController.navigationBar setNeedsDisplay]; 
} 

@end 

BarViewController.m

#import "UINavigationBar+CustomDraw.h" 

@implementation BarViewController 

- (void)viewWillAppear:(BOOL)animated 
{ 
    gNavbarBackgroundImageName = @"bar_navbar_background.png"; 
    [self.navigationController.navigationBar setNeedsDisplay]; 
} 

@end 

現在讓我們假設您想要顯示非風格的導航欄,例如在顯示Facebook登錄頁面(由其SDK提供)時。

使用此功能可以防止任何自定義繪製:

gNavbarBackgroundImageName = nil; 

注意一些蘋果的組件使用UINavigationBar的你可能沒有想到的地方。例如,MPMoviePlayerController使用自定義導航欄來顯示其用戶界面的上半部分 - 所以這是另一種您想要阻止自定義繪圖的情況。

+0

我設法解決了我的代碼的問題我只是添加方法在導航欄上添加右鍵,它現在可以看到我的編輯代碼。感謝您的回答。像這樣,如果我需要我的導航欄上的任何自定義元素,我只是喜歡子視圖和瞧,我會嘗試你的解決方案,因爲我認爲比我的優雅:) –

+0

噢,我完全忘了告訴你 - 確保你也添加可以禁用drawRect「hack」,因爲一旦顯示不應該定製的內容,這可能會嚴重傷害你。將立即添加到我的解決方案... – Till

+0

感謝您的補充 –