A.NavigationBar标题按钮
1.需求
  • 在“首页”的导航栏中部设置一个“首页”文字+箭头按钮
  • 统一设置样式
  • 根据实际文本长度调整宽度
  • 消除系统自带的点击高亮效果
  • 点击按钮,箭头上下颠倒
 
 
2.思路
  • 使用UIButton,设置文本和图片
  • 在initWithFrame统一样式
  • 创建一个继承UIButton的自定义类,重写文本和图片的绘图方法,互换位置
  • 设置一个标识成员变量,判断当前的按钮状态(弹出 or 缩回)
 
3.实现
(1)自定义继承UIButton的类 HVWNavigationBarTitleButton
 //
// HVWNavigationBarTitleButton.m
// HVWWeibo
//
// Created by hellovoidworld on 15/2/2.
// Copyright (c) 2015年 hellovoidworld. All rights reserved.
// #import "HVWNavigationBarTitleButton.h" @implementation HVWNavigationBarTitleButton /** 重写initWithFrame, 统一设置按钮的样式 */
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// 设置字体
self.titleLabel.font = HVWNavigationTitleFont;
[self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; // 文本右对齐
[self.titleLabel setTextAlignment:NSTextAlignmentRight]; // 取消图标高亮效果
[self setAdjustsImageWhenDisabled:NO]; // 图片居中
[self.imageView setContentMode:UIViewContentModeCenter]; } return self;
} /** 重写iamge的绘图方法 */
- (CGRect)imageRectForContentRect:(CGRect)contentRect {
CGFloat height = contentRect.size.height;
CGFloat width = height;
CGFloat x = self.size.width - width;
CGFloat y = ;
return CGRectMake(x, y, width, height);
} /** 重写title的绘图方法 */
- (CGRect)titleRectForContentRect:(CGRect)contentRect {
CGFloat height = contentRect.size.height;
// 文本宽度 = 按钮整体宽度 - 图片宽度
CGFloat width = self.height - height;
CGFloat x = ;
CGFloat y = ;
return CGRectMake(x, y, width, height);
} @end
 
(2)在“首页”控制器设置“标题按钮”:
HVWHomeViewController.m:
 - (void)viewDidLoad {
[super viewDidLoad]; // 添加导航控制器按钮
// 左边按钮
self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithImage:@"navigationbar_friendsearch" hightlightedImage:@"navigationbar_friendsearch_highlighted" target:self selector:@selector(searchFriend)]; // 右边按钮
self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithImage:@"navigationbar_pop" hightlightedImage:@"navigationbar_pop_highlighted" target:self selector:@selector(pop)]; // 设置标题按钮
HVWNavigationBarTitleButton *titleButton = [[HVWNavigationBarTitleButton alloc] init];
titleButton.height = ;
titleButton.width = ;
[titleButton setTitle:@"首页" forState:UIControlStateNormal];
[titleButton setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
// 设置背景图片
[titleButton setBackgroundImage:[UIImage resizedImage:@"navigationbar_filter_background_highlighted"] forState:UIControlStateHighlighted]; // 监听按钮点击事件,替换图标
[titleButton addTarget:self action:@selector(titleButtonClickd:) forControlEvents:UIControlEventTouchUpInside]; self.navigationItem.titleView = titleButton;
} /** 标题栏按钮点击事件 */
- (void) titleButtonClickd:(UIButton *) button {
self.titleButtonExtended = !self.titleButtonExtended; if (self.isTitleButtonExtended) {
[button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
} else {
[button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
}
} #mark:有希望依赖图片缓存,使用"=="判断当前按钮图片来决定按钮状态的,发现使用currentImage和新建一个UIImage(同一张图片)出来的地址并不一致!所以不能采用。
-(void)titleButtonClick:(UIButton *)titleButton
{
UIImage *titleImage=[UIImage imageWithName:@"navigationbar_arrow_down"]; if (titleButton.currentImage==titleImage) {
//换成箭头向上
[titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
}else
{
//换成箭头向下
[titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
}
}
 
B.导航栏标题按钮弹出框
1.需求
点击导航栏标题按钮弹出一个框
点击框外的其他地方,隐藏此框
 
 
2.思路
因为框的范围涉及到了导航栏,所以不能放在导航栏下的内容界面控制器上,要放在导航栏上
在框和导航栏的夹层放置一个全屏的(透明/半透明)的UIButton,用来监听框外点击
封装此功能,可以作为一个弹出菜单控件
 
(1)简单尝试直接在窗口上添加一个UIImageView
HVWHomeViewController:
 /** 标题栏按钮点击事件 */
- (void) titleButtonClickd:(UIButton *) button {
self.titleButtonExtended = !self.titleButtonExtended; if (self.isTitleButtonExtended) {
[button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal]; // 弹出框
UIView *window = [[UIApplication sharedApplication] keyWindow];
UIImageView *popView = [[UIImageView alloc] init];
popView.size = CGSizeMake(, );
popView.centerX = window.width * 0.5;
popView.y = ;
popView.image = [UIImage resizedImage:@"popover_background"];
[self.navigationController.view addSubview:popView]; } else {
[button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
}
}
 
 
(2)点击其他区域,隐藏弹出框
使用一个全屏透明/半透明UIButton夹在弹出框和底层的控件之间,监听点击事件
 /** 标题栏按钮点击事件 */
- (void) titleButtonClickd:(UIButton *) button {
self.titleButtonExtended = !self.titleButtonExtended; if (self.isTitleButtonExtended) {
[button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal]; UIView *window = [[UIApplication sharedApplication] keyWindow]; // 中间辅助覆盖层(帮助隐藏弹出框)
UIButton *coverLayer = [UIButton buttonWithType:UIButtonTypeCustom];
coverLayer.frame = window.bounds;
coverLayer.backgroundColor = [UIColor blackColor];
coverLayer.alpha = 0.2;
[window addSubview:coverLayer];
[coverLayer addTarget:self action:@selector(coverLayerClicked:) forControlEvents:UIControlEventTouchUpInside]; // 弹出框
UIImageView *popView = [[UIImageView alloc] init];
self.popView = popView;
popView.size = CGSizeMake(, );
popView.centerX = window.width * 0.5;
popView.y = ;
popView.userInteractionEnabled = YES; popView.image = [UIImage resizedImage:@"popover_background"];
[window addSubview:popView]; } else {
[button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
}
} /** 辅助覆盖层点击事件 */
- (void) coverLayerClicked:(UIButton *) button {
if (self.isTitleButtonExtended) {
[button removeFromSuperview];
[self.popView removeFromSuperview];
[self titleButtonClickd:self.titleButton];
}
}
 
 
 
(3)由于弹出框功能可能在多处用到,而且让控制器负责创建不合适,所以封装成一个类
封装成“弹出菜单”类HVWPopMenu(继承UIView)
内部包含:
背景图片
遮盖UIButton
一个内容界面 (如tableViewController),作为背景图片的子控件
 
 //
// HVWPopMenu.h
// HVWWeibo
//
// Created by hellovoidworld on 15/2/2.
// Copyright (c) 2015年 hellovoidworld. All rights reserved.
// #import <UIKit/UIKit.h> typedef enum {
PopMenuArrowLeft,
PopMenuArrowMid,
PopMenuArrowRight
} PopMenuArrow; @class HVWPopMenu;
@protocol HVWPopMenuDelegate <NSObject> @optional
- (void) popMenuDidHideMenu:(HVWPopMenu *) popMenu; @end @interface HVWPopMenu : UIView /** 背景兼内容容器 */
@property(nonatomic, strong) UIImageView *backgroundContainer; #pragma mark - 成员属性
/** 遮盖夹层 */
@property(nonatomic, strong) UIButton *coverLayer; /** 内容控件 */
@property(nonatomic, strong) UIView *contentView; /** 箭头位置 */
@property(nonatomic, assign) PopMenuArrow popMenuArrow; /** 遮盖夹层透明标识 */
@property(nonatomic, assign, getter=isDimCoverLayer) BOOL dimCoverLayer; /** 代理 */
@property(nonatomic, weak) id<HVWPopMenuDelegate> delegate; #pragma mark - 初始化方法
- (instancetype) initWithContentView:(UIView *) contentView;
+ (instancetype) popMenuWithContentView:(UIView *) contentView; #pragma mark - 使用方法
/** 弹出 */
- (void) showMenuInRect:(CGRect) rect; /** 隐藏 */
- (void) hideMenu; @end
 
 //
// HVWPopMenu.m
// HVWWeibo
//
// Created by hellovoidworld on 15/2/2.
// Copyright (c) 2015年 hellovoidworld. All rights reserved.
// #import "HVWPopMenu.h" @implementation HVWPopMenu #pragma mark - 初始化方法
- (instancetype) initWithContentView:(UIView *) contentView {
if (self = [super init]) {
self.contentView = contentView;
} return self;
} + (instancetype) popMenuWithContentView:(UIView *) contentView {
return [[self alloc] initWithContentView:contentView];
} /** 初始化子控件 */
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// 中间辅助覆盖层(帮助隐藏弹出框)
UIButton *coverLayer = [UIButton buttonWithType:UIButtonTypeCustom];
self.coverLayer = coverLayer;
[self setDimCoverLayer:YES];
[coverLayer addTarget:self action:@selector(coverLayerClicked) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:coverLayer]; // 添加背景容器
UIImageView *backgroundContainer = [[UIImageView alloc] init];
self.backgroundContainer = backgroundContainer;
backgroundContainer.userInteractionEnabled = YES;
[self setPopMenuArrow:PopMenuArrowMid];
[self addSubview:backgroundContainer];
} return self;
} /** 遮盖夹层点击事件 */
- (void) coverLayerClicked {
[self hideMenu];
} #pragma mark - 使用方法
/** 弹出 */
- (void) showMenuInRect:(CGRect) rect {
// 准备添加到当前主窗口上
UIView *window = [[UIApplication sharedApplication] keyWindow];
self.frame = window.bounds;
[window addSubview:self]; self.coverLayer.frame = window.bounds;
self.backgroundContainer.frame = rect; // 添加内容控件
if (self.contentView) {
CGFloat topMargin = ;
CGFloat leftMargin = ;
CGFloat bottomMargin = ;
CGFloat rightMargin = ; self.contentView.x = leftMargin;
self.contentView.y = topMargin;
self.contentView.width = self.backgroundContainer.width - leftMargin - rightMargin;
self.contentView.height = self.backgroundContainer.height - topMargin - bottomMargin; [self.backgroundContainer addSubview:self.contentView];
}
} /** 隐藏 */
- (void) hideMenu {
if ([self.delegate respondsToSelector:@selector(popMenuDidHideMenu:)]) {
[self.delegate popMenuDidHideMenu:self];
} [self removeFromSuperview];
} #pragma mark - 特性设置
/** 设置遮盖夹层是否透明 */
- (void)setDimCoverLayer:(BOOL)dimCoverLayer {
if (dimCoverLayer) { // 需要半透明模糊效果的
self.coverLayer.backgroundColor = [UIColor blackColor];
self.coverLayer.alpha = 0.2;
} else { // 全透明
self.coverLayer.backgroundColor = [UIColor clearColor];
self.coverLayer.alpha = 1.0;
}
} /** 设置弹出菜单顶部箭头位置:左、中、右 */
- (void)setPopMenuArrow:(PopMenuArrow)popMenuArrow {
_popMenuArrow = popMenuArrow; switch (popMenuArrow) {
case PopMenuArrowLeft:
self.backgroundContainer.image = [UIImage resizedImage:@"popover_background_left"];
break;
case PopMenuArrowMid:
self.backgroundContainer.image = [UIImage resizedImage:@"popover_background"];
break;
case PopMenuArrowRight:
self.backgroundContainer.image = [UIImage resizedImage:@"popover_background_right"];
break;
default:
break;
}
} @end
 
 //  HVWHomeViewController.m
/** 标题栏按钮点击事件 */
- (void) titleButtonClickd:(UIButton *) button {
self.titleButtonExtended = !self.titleButtonExtended; if (self.isTitleButtonExtended) {
[button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal]; // 添加弹出菜单
UITableView *tableView = [[UITableView alloc] init];
HVWPopMenu *popMenu = [HVWPopMenu popMenuWithContentView:tableView];
popMenu.delegate = self;
popMenu.dimCoverLayer = YES; // 模糊遮盖
popMenu.popMenuArrow = PopMenuArrowMid; // 中部箭头 // 弹出
[popMenu showMenuInRect:CGRectMake(, , , )]; } else {
[button setImage:[UIImage imageWithNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
}
} #pragma mark - HVWPopMenuDelegate
- (void)popMenuDidHideMenu:(HVWPopMenu *)popMenu {
UIButton *titleButton = (UIButton *)self.navigationItem.titleView;
[self titleButtonClickd:titleButton];
}
 
 

[iOS微博项目 - 1.5] - NavigationBar标题按钮的更多相关文章

  1. [iOS微博项目 - 3.4] - 获取用户信息

    github: https://github.com/hellovoidworld/HVWWeibo   A.获取用户信息 1.需求 获取用户信息并储存 把用户昵称显示在“首页”界面导航栏的标题上   ...

  2. [iOS微博项目 - 1.4] - 各种item NavigationBar & NavigationItem & BarButtonItem || TabBar & TabBarItem

    一.UINavigationItem1> 获得方式self.navigationItem // self是指控制器2> 作用可以用来设置当前控制器顶部导航栏的内容// 设置导航栏中间的内容 ...

  3. [iOS微博项目 - 3.1] - 发微博界面

    github: https://github.com/hellovoidworld/HVWWeibo   A.发微博界面:自定义UITextView 1.需求 用UITextView做一个编写微博的输 ...

  4. [iOS微博项目 - 1.0] - 搭建基本框架

    A.搭建基本环境   github: https://github.com/hellovoidworld/HVWWeibo   项目结构:   1.使用代码构建UI,不使用storyboard     ...

  5. [iOS微博项目 - 4.5] - 每条微博的底部工具条

    github: https://github.com/hellovoidworld/HVWWeibo A.每条微博的底部工具条 1.需求 每条微博底部都有一个工具条 显示3个按钮:评论.转发.赞 按钮 ...

  6. [iOS微博项目 - 3.6] - 获取未读消息

    github: https://github.com/hellovoidworld/HVWWeibo   A.获取登陆用户未读消息 1.需求 获取所有未读消息,包括新微博.私信.@.转发.关注等 把未 ...

  7. [iOS微博项目 - 3.0] - 手动刷新微博

    github: https://github.com/hellovoidworld/HVWWeibo   A.下拉刷新微博 1.需求 在“首页”界面,下拉到一定距离的时候刷新微博数据 刷新数据的时候使 ...

  8. [iOS微博项目 - 1.7] - 版本新特性

    A.版本新特性 1.需求 第一次使用新版本的时候,不直接进入app,而是展示新特性界面 github: https://github.com/hellovoidworld/HVWWeibo       ...

  9. [iOS微博项目 - 1.6] - 自定义TabBar

    A.自定义TabBar 1.需求 控制TabBar内的item的文本颜色(普通状态.被选中状态要和图标一致).背景(普通状态.被选中状态均为透明) 重新设置TabBar内的item位置,为下一步在Ta ...

随机推荐

  1. Android开发之SmsManager和SmsMessage

    Android的手机功能(通话与短信)都放在android.telephony包中,到了4.4时(也就是API19)android.provider.Telephony及相关类横空出世辅助电话功能以及 ...

  2. [HDOJ3635]Dragon Balls(并查集,路径压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3635 题意:有n个龙珠,n个城市.初始状态第i个龙珠在第i个城市里.接下来有两个操作: T A B:把 ...

  3. Akka的Actor模型及使用实例

    本文的绝大部分内容转载自rerun.me这一blog,老外写的东西就是好啊. ACTORS介绍 Anyone who has done multithreading in the past won't ...

  4. C#.NET U盘插拔监控

    [1]涉及的知识点 1) windows消息处理函数 ? 1 protected override void WndProc(ref Message m) 捕获Message的系统硬件改变发出的系统消 ...

  5. Windows SDK 实现不规则窗口介绍

    不规则窗口在程序界面设计中能提供非常好的用户体验,以下是我程序运行时的效果图: 以下是代码,注意需要修改一些简单的位置,如资源ID,项目的头文件等,这些是根据你创建的win32程序的项目名改变的,我的 ...

  6. sql server压缩数据库和日志文件

    DBCC SHRINKDATABASE 功能:压缩数据库 用法:DBCC SHRINKDATABASE tb_115sou_com 注意:只有产生许多未使用空间的操作(如截断表或删除表操作)后,执行收 ...

  7. 用RSA加密实现Web登录密码加密传输

    通常我们做一个Web应用程序的时候都需要登录,登录就要输入用户名和登录密码,并且,用户名和登录密码都是明文传输的,这样就有可能在中途被别人拦截,尤其是在网吧等场合. 这里顺带一个小插曲,我以前有家公司 ...

  8. tomcat 默认项目设置

    正常情况下,我们启动tomcat后,直接输入“http://localhost:端口/“ 后,默认访问道是webapp目录下的ROOT应用. 我们要通过上述方式访问自己的应用,有俩种方式. 第一:把自 ...

  9. acdream 1684 娜娜梦游仙境系列——莫名其妙的插曲 (gcd)

    题意:一开始有一个集合,集合里有n个不同的数,然后Alice(娜娜)与Bob轮流进行操作,每人都可以任意选择两个数a,b,不妨设a>b,不过要求a-b不在集合中,把a-b放入集合(集合元素个数只 ...

  10. Java [Leetcode 268]Missing Number

    题目描述: Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is ...