A.NavigationBar标题按钮
1.需求
  • 在“首页”的导航栏中部设置一个“首页”文字+箭头按钮
  • 统一设置样式
  • 根据实际文本长度调整宽度
  • 消除系统自带的点击高亮效果
  • 点击按钮,箭头上下颠倒
 
 
2.思路
  • 使用UIButton,设置文本和图片
  • 在initWithFrame统一样式
  • 创建一个继承UIButton的自定义类,重写文本和图片的绘图方法,互换位置
  • 设置一个标识成员变量,判断当前的按钮状态(弹出 or 缩回)
 
3.实现
(1)自定义继承UIButton的类 HVWNavigationBarTitleButton
 1 //
2 // HVWNavigationBarTitleButton.m
3 // HVWWeibo
4 //
5 // Created by hellovoidworld on 15/2/2.
6 // Copyright (c) 2015年 hellovoidworld. All rights reserved.
7 //
8
9 #import "HVWNavigationBarTitleButton.h"
10
11 @implementation HVWNavigationBarTitleButton
12
13 /** 重写initWithFrame, 统一设置按钮的样式 */
14 - (instancetype)initWithFrame:(CGRect)frame {
15 if (self = [super initWithFrame:frame]) {
16 // 设置字体
17 self.titleLabel.font = HVWNavigationTitleFont;
18 [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
19
20 // 文本右对齐
21 [self.titleLabel setTextAlignment:NSTextAlignmentRight];
22
23 // 取消图标高亮效果
24 [self setAdjustsImageWhenDisabled:NO];
25
26 // 图片居中
27 [self.imageView setContentMode:UIViewContentModeCenter];
28
29 }
30
31 return self;
32 }
33
34 /** 重写iamge的绘图方法 */
35 - (CGRect)imageRectForContentRect:(CGRect)contentRect {
36 CGFloat height = contentRect.size.height;
37 CGFloat width = height;
38 CGFloat x = self.size.width - width;
39 CGFloat y = 0;
40 return CGRectMake(x, y, width, height);
41 }
42
43 /** 重写title的绘图方法 */
44 - (CGRect)titleRectForContentRect:(CGRect)contentRect {
45 CGFloat height = contentRect.size.height;
46 // 文本宽度 = 按钮整体宽度 - 图片宽度
47 CGFloat width = self.height - height;
48 CGFloat x = 0;
49 CGFloat y = 0;
50 return CGRectMake(x, y, width, height);
51 }
52
53 @end
 
(2)在“首页”控制器设置“标题按钮”:
HVWHomeViewController.m:
 1 - (void)viewDidLoad {
2 [super viewDidLoad];
3
4 // 添加导航控制器按钮
5 // 左边按钮
6 self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithImage:@"navigationbar_friendsearch" hightlightedImage:@"navigationbar_friendsearch_highlighted" target:self selector:@selector(searchFriend)];
7
8 // 右边按钮
9 self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithImage:@"navigationbar_pop" hightlightedImage:@"navigationbar_pop_highlighted" target:self selector:@selector(pop)];
10
11 // 设置标题按钮
12 HVWNavigationBarTitleButton *titleButton = [[HVWNavigationBarTitleButton alloc] init];
13 titleButton.height = 35;
14 titleButton.width = 100;
15 [titleButton setTitle:@"首页" forState:UIControlStateNormal];
16 [titleButton setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
17 // 设置背景图片
18 [titleButton setBackgroundImage:[UIImage resizedImage:@"navigationbar_filter_background_highlighted"] forState:UIControlStateHighlighted];
19
20 // 监听按钮点击事件,替换图标
21 [titleButton addTarget:self action:@selector(titleButtonClickd:) forControlEvents:UIControlEventTouchUpInside];
22
23 self.navigationItem.titleView = titleButton;
24 }
25
26 /** 标题栏按钮点击事件 */
27 - (void) titleButtonClickd:(UIButton *) button {
28 self.titleButtonExtended = !self.titleButtonExtended;
29
30 if (self.isTitleButtonExtended) {
31 [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
32 } else {
33 [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
34 }
35 }
36
37 #mark:有希望依赖图片缓存,使用"=="判断当前按钮图片来决定按钮状态的,发现使用currentImage和新建一个UIImage(同一张图片)出来的地址并不一致!所以不能采用。
38 -(void)titleButtonClick:(UIButton *)titleButton
39 {
40 UIImage *titleImage=[UIImage imageWithName:@"navigationbar_arrow_down"];
41
42 if (titleButton.currentImage==titleImage) {
43 //换成箭头向上
44 [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
45 }else
46 {
47 //换成箭头向下
48 [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
49 }
50 }
 
B.导航栏标题按钮弹出框
1.需求
点击导航栏标题按钮弹出一个框
点击框外的其他地方,隐藏此框
 
 
2.思路
因为框的范围涉及到了导航栏,所以不能放在导航栏下的内容界面控制器上,要放在导航栏上
在框和导航栏的夹层放置一个全屏的(透明/半透明)的UIButton,用来监听框外点击
封装此功能,可以作为一个弹出菜单控件
 
(1)简单尝试直接在窗口上添加一个UIImageView
HVWHomeViewController:
 1 /** 标题栏按钮点击事件 */
2 - (void) titleButtonClickd:(UIButton *) button {
3 self.titleButtonExtended = !self.titleButtonExtended;
4
5 if (self.isTitleButtonExtended) {
6 [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
7
8 // 弹出框
9 UIView *window = [[UIApplication sharedApplication] keyWindow];
10 UIImageView *popView = [[UIImageView alloc] init];
11 popView.size = CGSizeMake(200, 200);
12 popView.centerX = window.width * 0.5;
13 popView.y = 55;
14 popView.image = [UIImage resizedImage:@"popover_background"];
15 [self.navigationController.view addSubview:popView];
16
17 } else {
18 [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
19 }
20 }
 
 
(2)点击其他区域,隐藏弹出框
使用一个全屏透明/半透明UIButton夹在弹出框和底层的控件之间,监听点击事件
 1 /** 标题栏按钮点击事件 */
2 - (void) titleButtonClickd:(UIButton *) button {
3 self.titleButtonExtended = !self.titleButtonExtended;
4
5 if (self.isTitleButtonExtended) {
6 [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
7
8 UIView *window = [[UIApplication sharedApplication] keyWindow];
9
10 // 中间辅助覆盖层(帮助隐藏弹出框)
11 UIButton *coverLayer = [UIButton buttonWithType:UIButtonTypeCustom];
12 coverLayer.frame = window.bounds;
13 coverLayer.backgroundColor = [UIColor blackColor];
14 coverLayer.alpha = 0.2;
15 [window addSubview:coverLayer];
16 [coverLayer addTarget:self action:@selector(coverLayerClicked:) forControlEvents:UIControlEventTouchUpInside];
17
18 // 弹出框
19 UIImageView *popView = [[UIImageView alloc] init];
20 self.popView = popView;
21 popView.size = CGSizeMake(200, 200);
22 popView.centerX = window.width * 0.5;
23 popView.y = 55;
24 popView.userInteractionEnabled = YES;
25
26 popView.image = [UIImage resizedImage:@"popover_background"];
27 [window addSubview:popView];
28
29 } else {
30 [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
31 }
32 }
33
34 /** 辅助覆盖层点击事件 */
35 - (void) coverLayerClicked:(UIButton *) button {
36 if (self.isTitleButtonExtended) {
37 [button removeFromSuperview];
38 [self.popView removeFromSuperview];
39 [self titleButtonClickd:self.titleButton];
40 }
41 }
 
 
 
(3)由于弹出框功能可能在多处用到,而且让控制器负责创建不合适,所以封装成一个类
封装成“弹出菜单”类HVWPopMenu(继承UIView)
内部包含:
背景图片
遮盖UIButton
一个内容界面 (如tableViewController),作为背景图片的子控件
 
 1 //
2 // HVWPopMenu.h
3 // HVWWeibo
4 //
5 // Created by hellovoidworld on 15/2/2.
6 // Copyright (c) 2015年 hellovoidworld. All rights reserved.
7 //
8
9 #import <UIKit/UIKit.h>
10
11 typedef enum {
12 PopMenuArrowLeft,
13 PopMenuArrowMid,
14 PopMenuArrowRight
15 } PopMenuArrow;
16
17 @class HVWPopMenu;
18 @protocol HVWPopMenuDelegate <NSObject>
19
20 @optional
21 - (void) popMenuDidHideMenu:(HVWPopMenu *) popMenu;
22
23 @end
24
25 @interface HVWPopMenu : UIView
26
27 /** 背景兼内容容器 */
28 @property(nonatomic, strong) UIImageView *backgroundContainer;
29
30 #pragma mark - 成员属性
31 /** 遮盖夹层 */
32 @property(nonatomic, strong) UIButton *coverLayer;
33
34 /** 内容控件 */
35 @property(nonatomic, strong) UIView *contentView;
36
37 /** 箭头位置 */
38 @property(nonatomic, assign) PopMenuArrow popMenuArrow;
39
40 /** 遮盖夹层透明标识 */
41 @property(nonatomic, assign, getter=isDimCoverLayer) BOOL dimCoverLayer;
42
43 /** 代理 */
44 @property(nonatomic, weak) id<HVWPopMenuDelegate> delegate;
45
46
47 #pragma mark - 初始化方法
48 - (instancetype) initWithContentView:(UIView *) contentView;
49 + (instancetype) popMenuWithContentView:(UIView *) contentView;
50
51 #pragma mark - 使用方法
52 /** 弹出 */
53 - (void) showMenuInRect:(CGRect) rect;
54
55 /** 隐藏 */
56 - (void) hideMenu;
57
58
59 @end
 
  1 //
2 // HVWPopMenu.m
3 // HVWWeibo
4 //
5 // Created by hellovoidworld on 15/2/2.
6 // Copyright (c) 2015年 hellovoidworld. All rights reserved.
7 //
8
9 #import "HVWPopMenu.h"
10
11 @implementation HVWPopMenu
12
13 #pragma mark - 初始化方法
14 - (instancetype) initWithContentView:(UIView *) contentView {
15 if (self = [super init]) {
16 self.contentView = contentView;
17 }
18
19 return self;
20 }
21
22 + (instancetype) popMenuWithContentView:(UIView *) contentView {
23 return [[self alloc] initWithContentView:contentView];
24 }
25
26 /** 初始化子控件 */
27 - (instancetype)initWithFrame:(CGRect)frame {
28 self = [super initWithFrame:frame];
29 if (self) {
30 // 中间辅助覆盖层(帮助隐藏弹出框)
31 UIButton *coverLayer = [UIButton buttonWithType:UIButtonTypeCustom];
32 self.coverLayer = coverLayer;
33 [self setDimCoverLayer:YES];
34 [coverLayer addTarget:self action:@selector(coverLayerClicked) forControlEvents:UIControlEventTouchUpInside];
35 [self addSubview:coverLayer];
36
37 // 添加背景容器
38 UIImageView *backgroundContainer = [[UIImageView alloc] init];
39 self.backgroundContainer = backgroundContainer;
40 backgroundContainer.userInteractionEnabled = YES;
41 [self setPopMenuArrow:PopMenuArrowMid];
42 [self addSubview:backgroundContainer];
43 }
44
45 return self;
46 }
47
48 /** 遮盖夹层点击事件 */
49 - (void) coverLayerClicked {
50 [self hideMenu];
51 }
52
53 #pragma mark - 使用方法
54 /** 弹出 */
55 - (void) showMenuInRect:(CGRect) rect {
56 // 准备添加到当前主窗口上
57 UIView *window = [[UIApplication sharedApplication] keyWindow];
58 self.frame = window.bounds;
59 [window addSubview:self];
60
61 self.coverLayer.frame = window.bounds;
62 self.backgroundContainer.frame = rect;
63
64 // 添加内容控件
65 if (self.contentView) {
66 CGFloat topMargin = 12;
67 CGFloat leftMargin = 5;
68 CGFloat bottomMargin = 8;
69 CGFloat rightMargin = 5;
70
71 self.contentView.x = leftMargin;
72 self.contentView.y = topMargin;
73 self.contentView.width = self.backgroundContainer.width - leftMargin - rightMargin;
74 self.contentView.height = self.backgroundContainer.height - topMargin - bottomMargin;
75
76 [self.backgroundContainer addSubview:self.contentView];
77 }
78 }
79
80 /** 隐藏 */
81 - (void) hideMenu {
82 if ([self.delegate respondsToSelector:@selector(popMenuDidHideMenu:)]) {
83 [self.delegate popMenuDidHideMenu:self];
84 }
85
86 [self removeFromSuperview];
87 }
88
89 #pragma mark - 特性设置
90 /** 设置遮盖夹层是否透明 */
91 - (void)setDimCoverLayer:(BOOL)dimCoverLayer {
92 if (dimCoverLayer) { // 需要半透明模糊效果的
93 self.coverLayer.backgroundColor = [UIColor blackColor];
94 self.coverLayer.alpha = 0.2;
95 } else { // 全透明
96 self.coverLayer.backgroundColor = [UIColor clearColor];
97 self.coverLayer.alpha = 1.0;
98 }
99 }
100
101
102 /** 设置弹出菜单顶部箭头位置:左、中、右 */
103 - (void)setPopMenuArrow:(PopMenuArrow)popMenuArrow {
104 _popMenuArrow = popMenuArrow;
105
106 switch (popMenuArrow) {
107 case PopMenuArrowLeft:
108 self.backgroundContainer.image = [UIImage resizedImage:@"popover_background_left"];
109 break;
110 case PopMenuArrowMid:
111 self.backgroundContainer.image = [UIImage resizedImage:@"popover_background"];
112 break;
113 case PopMenuArrowRight:
114 self.backgroundContainer.image = [UIImage resizedImage:@"popover_background_right"];
115 break;
116 default:
117 break;
118 }
119 }
120
121 @end
 
 1 //  HVWHomeViewController.m
2 /** 标题栏按钮点击事件 */
3 - (void) titleButtonClickd:(UIButton *) button {
4 self.titleButtonExtended = !self.titleButtonExtended;
5
6 if (self.isTitleButtonExtended) {
7 [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
8
9 // 添加弹出菜单
10 UITableView *tableView = [[UITableView alloc] init];
11 HVWPopMenu *popMenu = [HVWPopMenu popMenuWithContentView:tableView];
12 popMenu.delegate = self;
13 popMenu.dimCoverLayer = YES; // 模糊遮盖
14 popMenu.popMenuArrow = PopMenuArrowMid; // 中部箭头
15
16 // 弹出
17 [popMenu showMenuInRect:CGRectMake(50, 55, 200, 300)];
18
19 } else {
20 [button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
21 }
22 }
23
24 #pragma mark - HVWPopMenuDelegate
25 - (void)popMenuDidHideMenu:(HVWPopMenu *)popMenu {
26 UIButton *titleButton = (UIButton *)self.navigationItem.titleView;
27 [self titleButtonClickd:titleButton];
28 }

IOS--- NavigationBar标题按钮的更多相关文章

  1. [iOS微博项目 - 1.5] - NavigationBar标题按钮

    A.NavigationBar标题按钮 1.需求 在“首页”的导航栏中部设置一个“首页”文字+箭头按钮 统一设置样式 根据实际文本长度调整宽度 消除系统自带的点击高亮效果 点击按钮,箭头上下颠倒 gi ...

  2. iOS 添加导航按钮

    iOS设置导航按钮navigationBar中包含了这几个重要组成部分:leftBarButtonItem, rightBarButtonItem, backBarButtonItem, title. ...

  3. UINavigationController-自定义导航栏标题按钮.

    见视频0416 自定义导航栏标题按钮,在Bar Button Item中加入UIButton,设置UIButton的图片和标题,还可以自定义自定义UIButton实现特效按钮.

  4. Apple iOS 触控按钮 自动关闭 bug

    Apple iOS 触控按钮 自动关闭 bug bug 轻点 iPhone 背面可执行操作 您可以轻点两下或轻点三下 iPhone 背面以执行某些操作,如向上或向下滚动.截屏.打开"控制中心 ...

  5. IOS让返回按钮显示自定义标题而不是上个ViewController的title

    在开发IOS的时候发现当从一个ViewController跳转到另一个ViewController时,被跳转到的那个ViewController的返回按钮总是显示的是上个ViewController的 ...

  6. iOS 自定义NavigationBar右侧按钮rightBarButtonItem--button

    //两个按钮的父类view UIView *rightButtonView = [[UIView alloc] initWithFrame:CGRectMake(, , , )]; //历史浏览按钮 ...

  7. iOS 自定义NavigationBar右侧按钮rightBarButtonItem

    自定义右侧的一个按钮 UIBarButtonItem *myButton = [[UIBarButtonItem alloc] initWithTitle:@"主页" style: ...

  8. 【转】自定义iOS的Back按钮(backBarButtonItem)和pop交互手势(interactivepopgesturerecognizer) --- 不错

    原文网址:http://blog.csdn.net/joonsheng/article/details/41362499 序 说到自定义UINavigetionController的返回按钮,iOS7 ...

  9. iOS导航标题不居中问题(转载)

    前言 一直以来都让我很头痛的一个问题:系统自带的导航条,在标题文字很长时,进入到下一个界面,而下一个界面的标题也很长时,就会出现标题不居中显示. 曾经,我尝试过很多种办法,但是都没有从根上解决问题.下 ...

随机推荐

  1. leetcode面试准备: Game of Life

    leetcode面试准备: Game of Life 1 题目 According to the Wikipedia's article: "The Game of Life, also k ...

  2. Android游戏快速入门(一):基础储备

    智能手机时代已经到来了,手机的性能正在以你我惊讶的速度提升.那么手机游戏也在迅速发展,从简单的平面单机游戏不断的向复杂的3D网络游戏发展.所以,手机游戏的市场肯定也在不断扩张.那么,作为程序猿,我们也 ...

  3. 【HDOJ】2295 Radar

    DLX+二分. /* 2295 */ #include <iostream> #include <string> #include <map> #include & ...

  4. Good vs Evil

    Good vs Evil Description Middle Earth is about to go to war. The forces of good will have many battl ...

  5. poj1054The Troublesome Frog

    链接 想O(n*n)的DP  怎么想都超内存 看讨论有说hash+DP过的 实现比较繁琐 大部分直接暴力过了 直接枚举每个i j 与他们在一条线上的点 是不是给出的点 注意它必须能跳进和跳出 #inc ...

  6. 抽离CodeIgniter的数据库访问类 可以独立使用

    好吧,因为组织需要,最近又开始转战php了,业务逻辑都还好说,主要是老大要求在数据访问层上加上登录态验证.其实这种要求也是合理的,互联网服务要求上层保护下层,但下层不能完全相信上层.但是问题也就来了, ...

  7. 【转】android JNI编程 一些技巧(整理)

    原文网址:http://blog.csdn.net/linweig/article/details/5203716 本篇将介绍在JNI编程中如何传递参数和返回值. 首先要强调的是,native方法不但 ...

  8. ASP.NET MVC 3.0 Controller基础

    ASP.NET MVC 3.0 Controller基础   1.Controller类与方法 Controller(控制器)是ASP.NET MVC的核心,负责处理浏览器请求,并作出响应.Cotro ...

  9. 关于I/O的那点事

    转载请著名作者和地址http://www.cnblogs.com/scotth/p/3645489.html 1.关于 IO (fopen出现的错误 errorCode 183) 相关知识点: < ...

  10. 在Python中的格式化

    str= '@SES/%i/'%-1print strstr1='@SES/%i/'%1print str1str2='@SES/%i/'%2print str2 打印出的结果: @SES/-1/@S ...