自定義NavigationBar的思路

http://www.devdiv.com/uinavigationbar_-blog-21666-9081.html

話說自古武林劍法門派繁多,所以就有了每年9月9日的華山論劍。。。
iOS開發某些方面也是如此。拿自定義UINavigationBar這個很小的方面,也有N種方法,導致我在找尋答案的過程中走了很多彎路,多花了不少時間。現在就將這些方法做一下對比,誰優誰劣,留給讀者思考:

1.辟邪劍法
此劍法非常初級
只能實現系統定義的樣式。如下:

[代碼]c#/cpp/oc代碼:

1 [self.navigationController.navigationBar setBarStyle:UIBarStyleBlackOpaque];


2.松風劍法
此劍法中規中矩,能有不同變化。
可以隨意改變bar的顏色,如下:

[代碼]c#/cpp/oc代碼:

1 [self.navigationController.navigationBar setTintColor:[UIColor orangeColor]];

3.太極劍法
此劍法看似神奇,其實不厲害。
只能修改titleView,不能用於自定義背景,如下:

[代碼]c#/cpp/oc代碼:

1 UIImage *logo = [UIImage imageNamed:@"title_bg"];
2     [self.navigationItem setTitleView:[[[UIImageView alloc] initWithImage:logo] autorelease]];
如果你想用它修改背景一定會很失望的。。。

4.七星劍法
此劍法朴樹迷離,閃瞎你dog眼,不過有種種限制,特定條件才能發揮威力。
只對iOS5有效。如下:

[代碼]c#/cpp/oc代碼:

01 - (void)customizeAppearance
02 {
03     // Create resizable images
04     UIImage *gradientImage44 = [[UIImage imageNamed:@"surf_gradient_textured_44"]
05         resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
06     UIImage *gradientImage32 = [[UIImage imageNamed:@"surf_gradient_textured_32"]
07         resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
08   
09     // Set the background image for *all* UINavigationBars
10     [[UINavigationBar appearance] setBackgroundImage:gradientImage44
11         forBarMetrics:UIBarMetricsDefault];
12     [[UINavigationBar appearance] setBackgroundImage:gradientImage32
13         forBarMetrics:UIBarMetricsLandscapePhone];
14   
15     // Customize the title text for *all* UINavigationBars
16     [[UINavigationBar appearance] setTitleTextAttributes:
17         [NSDictionary dictionaryWithObjectsAndKeys:
18             [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
19             UITextAttributeTextColor,
20             [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
21             UITextAttributeTextShadowColor,
22             [NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
23             UITextAttributeTextShadowOffset,
24             [UIFont fontWithName:@"Arial-Bold" size:0.0],
25             UITextAttributeFont,
26             nil]];
27   
28 }<br>

簡單一點,就是下面的代碼:

[代碼]c#/cpp/oc代碼:

1 UINavigationBar *navBar = [myNavController navigationBar];
2 if ([navBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)])
3 {
4     // set globablly for all UINavBars
5     [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"brnlthr_nav.jpg"] forBarMetrics:UIBarMetricsDefault];
6   // ...
7 }

5.太極劍法
此劍法極簡,主要靠內力,但是同樣受到限制。
僅對iOS5之前版本有效,如下:

[代碼]c#/cpp/oc代碼:

1 @implementation UINavigationBar (CustomImage)
2 - (void)drawRect:(CGRect)rect {
3     // Drawing code
4     UIImage *image = [[UIImage imageNamed:@"header.png"] retain];
5     [image drawInRect:CGRectMake(0, 0,self.frame.size.width , self.frame.size.height)];
6     [image release];
7     }
8 @end

6.雌雄雙股劍法
將上述七星劍法和太極劍法接合,可形成雌雄雙股劍法,根據iOS版本不同發揮各自威力,從而不受限制。

7.兩儀劍法
此劍法源於太極劍法,所謂“太極生兩儀”。。。套路略有不同,不過還是僅限於iOS5之前版本:

[代碼]c#/cpp/oc代碼:

1 @interface MyNavigationBar : UINavigationBar
2  
3 @end

[代碼]c#/cpp/oc代碼:

01 @implementation MyNavigationBar
02  
03 - (void)drawRect:(CGRect)rect
04 {
05     [super drawRect:rect];
06 }
07 @end
08  
09 @implementation UINavigationBar (LazyNavigationBar)
10 + (Class)class {
11     return NSClassFromString(@"MyNavigationBar");
12 }
13  
14 -(void)drawRect:(CGRect)rect {
15     UIImage *backImage = [UIImage imageNamed:@"title_bg"];
16 [backImage drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];     
17 }
18 @end


8.金蛇劍法
此劍法勁道威猛,難以招架。

首先寫CustomNaviBar類:

[代碼]c#/cpp/oc代碼:

1 @interface CustomNaviBar : UINavigationBar
2 @end
3  
4 @implementation CustomNaviBar
5 - (void)drawRect:(CGRect)rect {
6     [[UIImage imageNamed:@"title_bg"] drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
7 }
8 @end


然後創建xib文件,拖一個UINavigationController出來,將UINavigationController中的UINavigationBar替換爲自定義的CustomNaviBar

然後,使用xib文件來創建UINavigationController:

[代碼]c#/cpp/oc代碼:

01 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
02 {
03     self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
04      
05     UINib *nib = [UINib nibWithNibName:@"Empty" bundle:nil];
06     UINavigationController* nc =  [[nib instantiateWithOwner:nil options:nil] objectAtIndex:0];//
07     self.window.rootViewController = nc;
08      
09     self.viewController = nil;
10      
11     [self.window makeKeyAndVisible];
12     return YES;
13 }


此方法通吃所有iOS平臺,有獨步武林盟主的實力。。

9.獨孤九劍
傳說中的終極劍法,威力無比。

適用所有IOS版本。

首先,爲appDelegate增加一個navigationController屬性:

[代碼]c#/cpp/oc代碼:

1 @interface DymAppDelegate : UIResponder <UIApplicationDelegate>
2 {
3     UINavigationController *navController_;
4 }
5 @property (strong, nonatomic) UIWindow *window;
6 @property (strong, nonatomic) DymViewController *viewController;
7  
8 @property (nonatomic, readonly, retain) UINavigationController *navigationController;
9 @end


然後,將此設爲rootViewController:

[代碼]c#/cpp/oc代碼:

01 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
02 {
03     self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
04      
05     self.viewController = [[[DymViewController alloc] initWithNibName:@"DymViewController"bundle:nil] autorelease];
06      
07     self.window.rootViewController = self.navigationController;
08      
09     self.viewController = nil;
10      
11     [self.window makeKeyAndVisible];
12     return YES;
13 }


下面是此劍法的心法:

[代碼]c#/cpp/oc代碼:

01 - (UINavigationController*)navigationController {
02     if (navController_ == nil) {
03         UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
04          
05         // Archive navigation controller for changing navigationbar class
06         [navController navigationBar];
07         NSMutableData *data = [[NSMutableData alloc] init];
08         NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
09         [archiver encodeObject:navController forKey:kRootKey];
10         [archiver finishEncoding];
11         [archiver release];
12         [navController release];
13          
14         // Unarchive it with changing navigationbar class
15         NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
16         [unarchiver setClass:[CustomNaviBar class]
17                 forClassName:NSStringFromClass([UINavigationBar class])];
18         navController_ = [[unarchiver decodeObjectForKey:kRootKey] retain];
19         [unarchiver release];
20          
21         [data release];
22     }
23     return navController_;
24 }

利用NSKeyedArchiver和NSKeyedUnarchiver來修改navigationbar。。。

獨孤九劍一出,金蛇劍法也爲之失色,實在是非常非常牛B的劍法啊,這次華山論劍,盟主之位就非他莫屬了。。哈哈哈

=======================================
後記:雖然這次獨孤九劍獲得了天下第一劍的稱號,但是世界之大,一定還有其他強大的劍法,在此拋磚引玉,以待明年華山再來爭鋒。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章