iOS開發項目篇—04添加導航欄的按鈕


iOS開發項目篇—04添加導航欄的按鈕

一、設置導航欄的按鈕

要求實現的效果:
            

說明:默認狀態下和高亮狀態下的圖片是不一樣的。

  按鈕的圖片需要設置默認狀態和高亮狀態時的顯示,系統了提供的下面方法

    viewController.navigationItem.leftBarButtonItem=[UIBarButtonItem alloc]initWithImage:<#(UIImage *)#> style:<#(UIBarButtonItemStyle)#> target:<#(id)#> action:<#(SEL)#>

在這里,我們需要設置兩種狀態下的圖片,顯然該方法無法滿足我們的需求。那么我們就位UIBarButtonItem增加一個分類,擴充一個方法,讓其能夠設置兩種狀態下的兩張圖片。

復制代碼
 1 //
 2 //  UIBarButtonItem+Extension.m
 3 //  04-微博導航欄上的按鈕
 4 //
 5 //  Created by apple on 14-7-4.
 6 // 7 //
 8 
 9 #import "UIBarButtonItem+Extension.h"
10 
11 @implementation UIBarButtonItem (Extension)
12 +(UIBarButtonItem *)itemWithImageName:(NSString *)ImageName highImageName:(NSString *)highImageName target:(id)target action:(SEL)action
13 {
14     //自定義UIView
15     UIButton *btn=[[UIButton alloc]init];
16     
17     //設置按鈕的背景圖片(默認/高亮)
18     [btn setBackgroundImage:[UIImage imageWithName:ImageName] forState:UIControlStateNormal];
19     [btn setBackgroundImage:[UIImage imageWithName:highImageName] forState:UIControlStateHighlighted];
20     
21     //設置按鈕的尺寸和圖片一樣大,使用了UIImage的分類
22     btn.size=btn.currentBackgroundImage.size;
23     [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
24     
25     return [[UIBarButtonItem alloc]initWithCustomView:btn];
26    
27 }
28 @end 
復制代碼

 

二、回退和跳轉到首頁

1.要求實現的效果:

程序啟動后,顯示的首頁界面:

點擊界面導航欄左角的按鈕,跳轉到ONE(注意導航欄上兩邊的按鈕)

點擊“跳轉到Two”按鈕,跳轉到Two(注意導航欄上右邊的按鈕)

點擊“跳轉到Three”按鈕,跳轉到Three

說明:點擊導航欄左邊的回退按鈕(《---)可以返回上一個界面,點擊導航欄右邊的按鈕(···)可以回到相應的首頁。

點擊THree中導航欄右邊的按鈕,回到home首頁

消息界面:

點擊cell,跳轉到一個新的界面(注意導航欄上得按鈕)

說明:在項目中有多個子頁面的導航欄,都需要用到回到上一頁和跳到首頁這一對BarButtonItem,我們知道導航欄上的按鈕設定需要設定對應的導航控制器來完成,要統一導航欄中在很多地方都用到的按鈕。

2.下面介紹三種實現的方法

(1)比較笨的實現方法是,在每個對應的頁面都實現一次下面的方法。

  如果是100個頁面需要這樣的導航欄,那么就需要把相同的代碼拷貝100份到相應的頁面,有必要嗎?這種方法確實可以實現,可總是相同的代碼,未免過於垃圾。

(2)抽出一個父類

  把公共代碼抽取到基本控制器中(抽取公共的父類),這種做法雖然能夠實現功能,但是這種做法是有問題的,不能這么做。

  所謂問題:繼承了UITableViewController就不能繼承基礎父類。

  用繼承不能保證所有的控制器都繼承公共的父類,所以不能使用繼承,一般繼承自系統的控制器就好了,不要有繼承約束。

  說明: 在iOS中控制器很少用繼承,因為ios中提供了多種控制器

(3)攔截push操作

通過分析,我們可以通過直接在自定義的導航控制器中進行設置,攔截push操作。當push的時候,對棧進行判斷,只要當前push的不是棧底的控制器,那么就統一設置導航欄的leftBarButtonItem和rightBarButtonItem,在他們的監聽方法中分別完成回到前一頁和回到首頁操作。

復制代碼
 1 -(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
 2 {
 3     //如果現在push的不是棧頂控制器,那么久隱藏tabbar工具條
 4     if (self.viewControllers.count>0) {
 5         viewController.hidesBottomBarWhenPushed=YES;
 6         
 7         //攔截push操作,設置導航欄的左上角和右上角按鈕
 8         viewController.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_back" highImageName:@"navigationbar_back_highlighted" target:self action:@selector(back)];
 9         viewController.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_more" highImageName:@"navigationbar_more_highlighted" target:self action:@selector(more)];
10         
11     }
12     [super pushViewController:viewController animated:YES];
13 }
14 
15 -(void)back
16 {
17 #warning 這里用的是self, 因為self就是當前正在使用的導航控制器
18     [self popViewControllerAnimated:YES];
19 }
20 
21 -(void)more
22 {
23     [self popToRootViewControllerAnimated:YES];
24 }
復制代碼

如果在某個頁面中,我們不需要系統設定的導航欄按鈕,那么可以直接在相應的頁面對導航欄的leftBarButtonItem和rightBarButtonItem進行重新設置,覆蓋系統設置。

如Two界面,導航欄右邊的按鈕,代碼如下:

復制代碼
1 //重置導航欄右上角的按鈕,以覆蓋系統統一的方案
2 -(void)viewDidLoad
3 {
4     [super viewDidLoad];
5     
6     self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"真的可以設置" style:UIBarButtonItemStyleDone target:self action:nil];
7 }
復制代碼

提示:自定義導航控制器的優點~能夠攔截到很多操作。

3.第三種方法的實現

(1)導入必要的圖片資源

說明:硬盤對硬盤的拷貝

(2)新建三個頁面,演示效果

 設置點擊按鈕后跳轉的代碼:

復制代碼
 1 //
 2 //  YYOneViewController.m
 3 //  04-微博導航欄上的按鈕
 4 //
 5 //  Created by apple on 14-7-4.
 6 // 7 //
 8 
 9 #import "YYOneViewController.h"
10 #import "YYTwoViewController.h"
11 
12 @interface YYOneViewController ()
13 - (IBAction)jump2Two;
14 
15 @end
16 
17 @implementation YYOneViewController
18 
19 //點擊按鈕跳轉到第二個界面
20 - (IBAction)jump2Two {
21     YYTwoViewController *two=[[YYTwoViewController alloc]init];
22     two.title=@"Two";
23     [self.navigationController pushViewController:two animated:YES];
24 }
25 @end
復制代碼

 

三、實現代碼

1.UIImage的分類,擴充方法:

UIImage+Extension.h文件

復制代碼
 1 //
 2 //  UIImage+Extension.h
 3 //  
 4 //
 5 //  Created by apple on 14-7-3.
 6 // 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @interface UIImage (Extension)
12 + (UIImage *)imageWithName:(NSString *)name;
13 @end
復制代碼

UIImage+Extension.m文件

復制代碼
 1 //
 2 //  UIImage+Extension.m
 3 //  
 4 //
 5 //  Created by apple on 14-7-3.
 6 // 
 7 //
 8 
 9 #import "UIImage+Extension.h"
10 
11 @implementation UIImage (Extension)
12 + (UIImage *)imageWithName:(NSString *)name
13 {
14     UIImage *image = nil;
15     if (iOS7) { // 處理iOS7的情況
16         NSString *newName = [name stringByAppendingString:@"_os7"];
17         image = [UIImage imageNamed:newName];
18     }
19     
20     if (image == nil) {
21         image = [UIImage imageNamed:name];
22     }
23     return image;
24 }
25 @end
復制代碼

2.UIBarButtonItem的分類,擴充方法:

UIBarButtonItem+Extension.h文件

復制代碼
 1 //  UIBarButtonItem+Extension.h
 2 //  04-微博導航欄上的按鈕
 3 //
 4 //  Created by apple on 14-7-4.
 5 
 6 
 7 #import <UIKit/UIKit.h>
 8 
 9 @interface UIBarButtonItem (Extension)
10 +(UIBarButtonItem *)itemWithImageName:(NSString *)ImageName highImageName:(NSString *)highImageName target:(id)target action:(SEL)action;
11 @end
復制代碼

UIBarButtonItem+Extension.m文件

復制代碼
 1 //
 2 //  UIBarButtonItem+Extension.m
 3 //  04-微博導航欄上的按鈕
 4 //
 5 //
 6 
 7 #import "UIBarButtonItem+Extension.h"
 8 
 9 @implementation UIBarButtonItem (Extension)
10 +(UIBarButtonItem *)itemWithImageName:(NSString *)ImageName highImageName:(NSString *)highImageName target:(id)target action:(SEL)action
11 {
12     //自定義UIView
13     UIButton *btn=[[UIButton alloc]init];
14     
15     //設置按鈕的背景圖片(默認/高亮)
16     [btn setBackgroundImage:[UIImage imageWithName:ImageName] forState:UIControlStateNormal];
17     [btn setBackgroundImage:[UIImage imageWithName:highImageName] forState:UIControlStateHighlighted];
18     
19     //設置按鈕的尺寸和圖片一樣大,使用了UIImage的分類
20     btn.size=btn.currentBackgroundImage.size;
21     [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
22     
23     return [[UIBarButtonItem alloc]initWithCustomView:btn];
24    
25 }
26 @end
復制代碼

3..UIView的分類,擴充方法:

UIView+Extension.h文件

復制代碼
 1 //
 2 //  UIView+Extension.h
 3 //
 4 
 5 #import <UIKit/UIKit.h>
 6 
 7 @interface UIView (Extension)
 8 @property (nonatomic, assign) CGFloat x;
 9 @property (nonatomic, assign) CGFloat y;
10 @property (nonatomic, assign) CGFloat width;
11 @property (nonatomic, assign) CGFloat height;
12 @property (nonatomic, assign) CGSize size;
13 @end
復制代碼

UIView+Extension.m文件

復制代碼
 1 //
 2 //  UIView+Extension.m
 3 //
 4 
 5 #import "UIView+Extension.h"
 6 
 7 @implementation UIView (Extension)
 8 
 9 - (void)setX:(CGFloat)x
10 {
11     CGRect frame = self.frame;
12     frame.origin.x = x;
13     self.frame = frame;
14 }
15 
16 - (CGFloat)x
17 {
18     return self.frame.origin.x;
19 }
20 
21 - (void)setY:(CGFloat)y
22 {
23     CGRect frame = self.frame;
24     frame.origin.y = y;
25     self.frame = frame;
26 }
27 
28 - (CGFloat)y
29 {
30     return self.frame.origin.y;
31 }
32 
33 - (void)setWidth:(CGFloat)width
34 {
35     CGRect frame = self.frame;
36     frame.size.width = width;
37     self.frame = frame;
38 }
39 
40 - (CGFloat)width
41 {
42     return self.frame.size.width;
43 }
44 
45 - (void)setHeight:(CGFloat)height
46 {
47     CGRect frame = self.frame;
48     frame.size.height = height;
49     self.frame = frame;
50 }
51 
52 - (CGFloat)height
53 {
54     return self.frame.size.height;
55 }
56 
57 - (void)setSize:(CGSize)size
58 {
59 //    self.width = size.width;
60 //    self.height = size.height;
61     CGRect frame = self.frame;
62     frame.size = size;
63     self.frame = frame;
64 }
65 
66 - (CGSize)size
67 {
68     return self.frame.size;
69 }
70 
71 @end
復制代碼

4.核心代碼,攔截push操作

YYUINavigationViewController.m文件

復制代碼
 1 //
 2 //  YYUINavigationViewController.m
 3 //
 4 
 5 #import "YYNavigationViewController.h"
 6 
 7 @interface YYNavigationViewController ()
 8 
 9 @end
10 
11 @implementation YYNavigationViewController
12 
13 - (void)viewDidLoad
14 {
15     [super viewDidLoad];
16 }
17 
18 -(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
19 {
20     //如果現在push的不是棧頂控制器,那么久隱藏tabbar工具條
21     if (self.viewControllers.count>0) {
22         viewController.hidesBottomBarWhenPushed=YES;
23         
24         //攔截push操作,設置導航欄的左上角和右上角按鈕
25         viewController.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_back" highImageName:@"navigationbar_back_highlighted" target:self action:@selector(back)];
26         viewController.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_more" highImageName:@"navigationbar_more_highlighted" target:self action:@selector(more)];
27         
28     }
29     [super pushViewController:viewController animated:YES];
30 }
31 
32 -(void)back
33 {
34 #warning 這里用的是self, 因為self就是當前正在使用的導航控制器
35     [self popViewControllerAnimated:YES];
36 }
37 
38 -(void)more
39 {
40     [self popToRootViewControllerAnimated:YES];
41 }
42 
43 @end
復制代碼

5.首頁的主控制器代碼,設置首頁的導航欄按鈕

YYHomeTableViewController.m文件

復制代碼
 1 //
 2 //  YYHomeTableViewController.m
 3 //
 4 
 5 #import "YYHomeTableViewController.h"
 6 #import "YYOneViewController.h"
 7 
 8 @interface YYHomeTableViewController ()
 9 
10 @end
11 
12 @implementation YYHomeTableViewController
13 
14 - (id)initWithStyle:(UITableViewStyle)style
15 {
16     self = [super initWithStyle:style];
17     if (self) {
18         // Custom initialization
19     }
20     return self;
21 }
22 
23 - (void)viewDidLoad
24 {
25     [super viewDidLoad];
26     
27     //設置導航欄的按鈕
28     self.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_friendsearch" highImageName:@"navigationbar_friendsearch_highlighted" target:self action:@selector(friendsearch)];
29     self.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_pop" highImageName:@"navigationbar_pop_highlighted" target:self action:@selector(pop)];
30 }
31 -(void)pop
32 {
33     YYLog(@"---POP---");
34 }
35 -(void)friendsearch
36 {
37     //跳轉到one這個子控制器界面
38     YYOneViewController *one=[[YYOneViewController alloc]init];
39     one.title=@"One";
40     //拿到當前控制器
41     [self.navigationController pushViewController:one animated:YES];
42     
43 }
44 
45 #pragma mark - Table view data source
46 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
47 {
48     return 20;
49 }
50 
51 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
52 {
53     static NSString *ID = @"cell";
54     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
55     if (!cell) {
56         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
57     }
58     cell.textLabel.text = [NSString stringWithFormat:@"%d----首頁測試數據", indexPath.row];
59     return cell;
60 }
61 
62 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
63 {
64     //點擊cell的時候,跳到下一個界面
65     UIViewController *newVc = [[UIViewController alloc] init];
66     newVc.view.backgroundColor = [UIColor redColor];
67     newVc.title = @"新控制器";
68     [self.navigationController pushViewController:newVc animated:YES];
69 }
70 
71 @end
復制代碼

6.Two代碼

 YYTwoViewController.m文件

復制代碼
 1 //
 2 //  YYTwoViewController.m
 3 //
 4 
 5 #import "YYTwoViewController.h"
 6 #import "YYThreeViewController.h"
 7 
 8 @interface YYTwoViewController ()
 9 - (IBAction)jump2Three;
10 
11 @end
12 
13 @implementation YYTwoViewController
14 
15 
16 //重置導航欄右上角的按鈕,以覆蓋系統統一的方案
17 -(void)viewDidLoad
18 {
19     [super viewDidLoad];
20     
21     self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"真的可以設置" style:UIBarButtonItemStyleDone target:self action:nil];
22 }
23 //點擊按鈕,跳轉到第三個界面
24 - (IBAction)jump2Three {
25     YYThreeViewController *three=[[YYThreeViewController alloc]init];
26     three.title=@"Three";
27     [self.navigationController pushViewController:three animated:YES];
28 }
29 @end
復制代碼

7.項目的PCH文件

復制代碼
 1 //
 2 //  Prefix header
 3 //
 4 //  The contents of this file are implicitly included at the beginning of every source file.
 5 //
 6 
 7 #import <Availability.h>
 8 
 9 #ifndef __IPHONE_5_0
10 #warning "This project uses features only available in iOS SDK 5.0 and later."
11 #endif
12 
13 #ifdef __OBJC__
14     #import <UIKit/UIKit.h>
15     #import <Foundation/Foundation.h>
16     #import "UIImage+Extension.h"
17     #import "UIBarButtonItem+Extension.h"
18     #import "UIView+Extension.h"
19 
20 #ifdef DEBUG // 調試狀態, 打開LOG功能
21 #define YYLog(...) NSLog(__VA_ARGS__)
22 #else // 發布狀態, 關閉LOG功能
23 #define YYLog(...)
24 #endif
25 
26 
27 // 隨機色
28 #define YYRandomColor [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0]
29 
30 // 是否為iOS7
31 #define iOS7 ([[UIDevice currentDevice].systemVersion doubleValue] >= 7.0)
32 #endif
復制代碼

 

四、補充說明

(1)mac--->ios

如果打開一個以前的項目,項目明明是一個ios項目,但是卻顯示為mac項目:

調整辦法如下:

找到存儲路徑,右鍵顯示包內容

包里的文件顯示如下:

其中xcuserdata相當於是緩存,把該文件刪除之后,重新打開項目即可。

(2)關於log的打印

在pch文件中,進行條件編譯

1 #ifdef DEBUG // 調試狀態, 打開LOG功能
2 #define YYLog(...) NSLog(__VA_ARGS__)
3 #else // 發布狀態, 關閉LOG功能
4 #define YYLog(...)
5 #endif

在需要使用Nslog打印的時候,直接使用YYlog即可。

(3)設置導航欄為黑色不透明

 
 
標簽:  IOS開發項目篇
綠色通道:  好文要頂  關注我  收藏該文 與我聯系 
0
0
 
(請您對文章做出評價)
 
« 上一篇: iOS開發項目篇—03添加導航控制器
» 下一篇: iOS開發項目篇—05主題設置

posted on 2014-07-04 23:37 文頂頂 閱讀(4983) 評論(2) 編輯 收藏

 

評論

#1樓 2015-01-24 13:49 搬磚的蝸牛  

 

在UIBarButtonItem+Extension.m 中為btm 設置按鈕尺寸報錯

btn.size = btn.currentBackgroundImage.size;
【property ‘size’ not found on object of type ‘UIButton】

或許可以用CGRect frame = btn.frame;
frame.size = btn.currentBackgroundImage.size;
btn.frame = frame;
代替。
   回復引用

 

#2樓 2015-01-26 11:10 搬磚的蝸牛  

 

博主你好,
//攔截push操作,設置導航欄的左上角和右上角按鈕
這里面的方法 Xcode 報錯說選擇了未知類的方法 itemWithImageName ,
事實上我都是一樣在.PCH導入了頭文件,按Command +左鍵 也能跳轉過去這個方法上去,但是就是無法運行編譯,這是為什么啊?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM