IOS--- NavigationBar标题按钮
来源:互联网 发布:程序员加班傻 编辑:程序博客网 时间:2024/05/02 04:25
A.NavigationBar标题按钮
1.需求
- 在“首页”的导航栏中部设置一个“首页”文字+箭头按钮
- 统一设置样式
- 根据实际文本长度调整宽度
- 消除系统自带的点击高亮效果
- 点击按钮,箭头上下颠倒
github: https://github.com/hellovoidworld/HVWWeibo
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 HVWNavigationBarTitleButton12 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 *)titleButton39 {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 }else46 {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 PopMenuArrowRight15 } PopMenuArrow;16 17 @class HVWPopMenu;18 @protocol HVWPopMenuDelegate <NSObject>19 20 @optional21 - (void) popMenuDidHideMenu:(HVWPopMenu *) popMenu;22 23 @end24 25 @interface HVWPopMenu : UIView26 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 - HVWPopMenuDelegate25 - (void)popMenuDidHideMenu:(HVWPopMenu *)popMenu {26 UIButton *titleButton = (UIButton *)self.navigationItem.titleView;27 [self titleButtonClickd:titleButton];28 }
0 0
- IOS--- NavigationBar标题按钮
- 自定义NavigationBar的返回按钮和标题
- NavigationBar 添加、标题/左右按钮/颜色
- NavigationBar--修改返回按钮的标题
- iOS导航栏NavigationBar的颜色,按钮和标题以及字体颜色
- ios 修改navigationBar标题颜色swift版
- IOS开发--在navigationBar上加按钮
- 更改UINavigationController中NavigationBar返回按钮的标题
- UINavigationController的navigationBar的常用设置(按钮,标题,颜色)
- 自定义UINavigationController 标题、左右边按钮 navigationbar 设置多个按钮
- iOS开发自定义navigationBar上的左右按钮
- (iOS开发)导航栏navigationBar中间添加按钮
- iOS中导航栏navigationBar返回按钮----常用设置
- IOS-NavigationBar
- iOS-NavigationBar
- <iOS>NavigationBar
- navigationbar 的标题
- 自定义NavigationBar按钮
- Dynamics CRM2016 站点地图Bug之KnowledgeArticle不显示
- arcgis js 笔记
- Java网络编程总结 --URLConnection
- Oracle创建表空间和用户
- 基于SearchView实时搜索结果
- IOS--- NavigationBar标题按钮
- icare3.0系统病人资料登记注意事项-----运维日志13
- 10个Android开源个性化View控件
- str
- Linux中Oracle环境变量配制
- Linux学习笔记之<查看环境变量>
- 新浪32亿条实时日志的Elasticsearch优化
- NSString超全总结
- PHP环境搭建