首页 > 代码库 > iOS开发项目—04添加导航栏的按钮

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)action13 {14     //自定义UIView15     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)back16 {17 #warning 这里用的是self, 因为self就是当前正在使用的导航控制器18     [self popViewControllerAnimated:YES];19 }20 21 -(void)more22 {23     [self popToRootViewControllerAnimated:YES];24 }

如果在某个页面中,我们不需要系统设定的导航栏按钮,那么可以直接在相应的页面对导航栏的leftBarButtonItem和rightBarButtonItem进行重新设置,覆盖系统设置。

如Two界面,导航栏右边的按钮,代码如下:

1 //重置导航栏右上角的按钮,以覆盖系统统一的方案2 -(void)viewDidLoad3 {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 @end16 17 @implementation YYOneViewController18 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 *)name13 {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)action11 {12     //自定义UIView13     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)x10 {11     CGRect frame = self.frame;12     frame.origin.x = x;13     self.frame = frame;14 }15 16 - (CGFloat)x17 {18     return self.frame.origin.x;19 }20 21 - (void)setY:(CGFloat)y22 {23     CGRect frame = self.frame;24     frame.origin.y = y;25     self.frame = frame;26 }27 28 - (CGFloat)y29 {30     return self.frame.origin.y;31 }32 33 - (void)setWidth:(CGFloat)width34 {35     CGRect frame = self.frame;36     frame.size.width = width;37     self.frame = frame;38 }39 40 - (CGFloat)width41 {42     return self.frame.size.width;43 }44 45 - (void)setHeight:(CGFloat)height46 {47     CGRect frame = self.frame;48     frame.size.height = height;49     self.frame = frame;50 }51 52 - (CGFloat)height53 {54     return self.frame.size.height;55 }56 57 - (void)setSize:(CGSize)size58 {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)size67 {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 @end10 11 @implementation YYNavigationViewController12 13 - (void)viewDidLoad14 {15     [super viewDidLoad];16 }17 18 -(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated19 {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)back33 {34 #warning 这里用的是self, 因为self就是当前正在使用的导航控制器35     [self popViewControllerAnimated:YES];36 }37 38 -(void)more39 {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 @end11 12 @implementation YYHomeTableViewController13 14 - (id)initWithStyle:(UITableViewStyle)style15 {16     self = [super initWithStyle:style];17     if (self) {18         // Custom initialization19     }20     return self;21 }22 23 - (void)viewDidLoad24 {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)pop32 {33     YYLog(@"---POP---");34 }35 -(void)friendsearch36 {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 source46 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section47 {48     return 20;49 }50 51 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath52 {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 *)indexPath63 {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 @end12 13 @implementation YYTwoViewController14 15 16 //重置导航栏右上角的按钮,以覆盖系统统一的方案17 -(void)viewDidLoad18 {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_010 #warning "This project uses features only available in iOS SDK 5.0 and later."11 #endif12 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 #endif25 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 // 是否为iOS731 #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)设置导航栏为黑色不透明