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     [email protected]"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     [email protected]"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     [email protected]"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开发项目篇

绿色通道: 好文要顶 关注我 收藏该文与我联系 

文顶顶
关注 - 11
粉丝 - 625

+加关注

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;
代替。

支持(0)反对(0)

回复引用

#2楼 2015-01-26 11:10 搬砖的蜗牛

博主你好,
//拦截push操作,设置导航栏的左上角和右上角按钮
这里面的方法 Xcode 报错说选择了未知类的方法 itemWithImageName ,
事实上我都是一样在.PCH导入了头文件,按Command +左键 也能跳转过去这个方法上去,但是就是无法运行编译,这是为什么啊?

时间: 2024-08-04 03:34:21

iOS开发项目篇—04添加导航栏的按钮的相关文章

iOS开发项目篇—03添加导航控制器

iOS开发项目篇—03添加导航控制器 一.简单说明 分析:分析微博应用,我们需要给每个子控制器都添加一个导航控制器(每个子控制器的导航不一样),所以需要新建一个导航控制器,然后把该导航控制器作为window的根控制器,添加的四个子控制器,分别添加在导航控制器上,也就是说整个项目采用当前主流的UI框架,一个UITabBarController管理着四个UINavigationController,而每个UINavigationController则分别管理着“首页”.“消息”.“发现”和“我”这四

iOS开发项目—04添加导航栏的按钮

iOS开发项目—04添加导航栏的按钮 一.设置导航栏的按钮 要求实现的效果:             说明:默认状态下和高亮状态下的图片是不一样的. 按钮的图片需要设置默认状态和高亮状态时的显示,系统了提供的下面方法 viewController.navigationItem.leftBarButtonItem=[UIBarButtonItem alloc]initWithImage:<#(UIImage *)#> style:<#(UIBarButtonItemStyle)#>

iOS开发项目篇—32添加上拉刷新数据

iOS开发项目篇—32添加上拉刷新数据 一.简单说明 图片示意 思路:可以自定义一个view(示意xib),在view中添加一个label和菊花,指示状态.把这个view设置为tableView的底部视图. 二.实现过程 1.新建一个类和xib,关联 (1)创建一个类,让其继承自UIView (2)创建一个xib文件,用来定义上拉提示框 (3)定义的xib文件,把类和xib文件进行关联 2.实现代码: YYlaodStatusesFooter.h文件 1 // 2 // YYlaodStatus

iOS开发项目篇—02添加子控制器以及项目分层

iOS开发项目篇—02添加子控制器以及项目分层 一.添加子控制器 1.设置根控制器(自定义) 说明:分析新浪微博应用,观察其整体建构层次.而系统的控制器不能满足项目开发的需求,这里把项目中原有的控制器删除. 自己定义一个TabBarViewController类.让这个类作为window窗口的根控制器. YYAppDelegate.m文件代码: 1 #import "YYAppDelegate.h" 2 #import "YYTabBarViewController.h&qu

iOS开发项目篇—28自定义UITextView

iOS开发项目篇—28自定义UITextView 一.简单说明 1.要实现的效果 2.分析 (1)UITextField 1.最多只能输入一行文字 2.能设置提醒文字(placehoder) 3.不具备滚动功能 (2)UITextView 1.能输入N行文字(N>0) 2.不能设置提醒文字(没有placehoder属性) 3.具备滚动功能 需求:技能输入多行文字,又具备文字提醒功能. 这里选择自定义一个类,让其继承自UITextView类,为其添加一个设置文字提醒的功能. 二.实现 自定义UI控

iOS开发项目篇—36封装微博业务

iOS开发项目篇—36封装微博业务 一.简单说明 1.请求参数面向模型 2.请求结果面向模型 3.对控制器来说应该屏蔽业务细节.不让控制器关心(知道)业务细节,它只需要知道自己在做某个业务 @通过一个专门的业务处理类:处理微博业务细节 说明: 业务:加载新的微博首页数据 实现:给新浪服务器发送一个GET请求 业务:加载更多的首页微博数据 实现1:给新浪服务器发送一个GET请求 实现2:去沙盒中加载以前离线缓存的微博数据  二.实现 1.新建一个微博业务处理类,继承自NSObject 微博业务处理

iOS开发项目篇—34获取用户信息

iOS开发项目篇—34获取用户信息 一.简单说明 需求:获取当前用户的昵称 ,需要获取当前登录用户的个人信息. 查看接口 要求传递的参数 这里要获取的时用户的昵称(所以使用用户id作为参数传入) 二.实现代码 1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 5 //设置导航栏内容 6 [self setupNavBar]; 7 8 //集成刷新控件 9 [self setupRefresh]; 10 11 //设置用户的昵称为标题 12 [s

iOS开发项目篇—29自定义工具条

iOS开发项目篇—29自定义工具条 一.简单说明 1.实现效果: 2.实现思路: (1)尝试: 1 //添加子控件 2 -(void)setupTextView 3 { 4 //1.创建输入控件 5 YYTextView *textView=[[YYTextView alloc]init]; 6 //设置frame 7 textView.frame=self.view.bounds; 8 [self.view addSubview:textView]; 9 self.textView=textV

iOS开发项目篇—27自定义UITabBar

iOS开发项目篇—27自定义UITabBar 一.自定义 思路: (1)新建一个继承自UITabBar的类,自定义一个UITabBar (2)用自定义的UITabBar换掉系统的UItabBar(使用了KVC) (3)监听控制器的切换,只要控制器一切换,就调用代理方法强制重新布局子控件(内部会调用layoutSubviews). YYTabBar.m文件代码: 1 // 2 // YYTabBar.m 3 // 4 5 #import "YYTabBar.h" 6 7 @interfa