【转】自定义iOS的Back按钮(backBarButtonItem)和pop交互手势(interactivepopgesturerecognizer) --- 不错
原文网址:http://blog.csdn.net/joonsheng/article/details/41362499
序
说到自定义UINavigetionController的返回按钮,iOS7以后,多了一个“<” 这样的返回图标,而目前主流的应用,都是只保留了“<”,而去掉了文字,那么怎么样自定义一个自己的“<"按钮,或者用系统的“<”,但不要文字呢?
1.设置中的返回按钮(带文字)
2.音乐中播放时(不带文字)
1、直接上答案
- //下面这两句是让系统的返回按钮的文字为空,从而达到隐藏文字的作用
- UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:nil];
- self.navigationItem.backBarButtonItem = backItem;
- //这句就是push了,所以在push前加上这样一句,就保留了系统的自带的“<",并且文字为空
- [self.navigationController pushViewController:registerVC animated:YES];
注:本文代码,如果没有说明,都是从A导航视图push到B导航视图时,在A导航视图里设置的代码。
看图:
2、带着问题看答案:
1、上面的方法,只是利用了系统的自带"<", 有人可能就问,那如果我想自定义图标呢?
- //下面两行就是自定义,替换系统的“<"图标
- 【1】 [self.navigationController.navigationBar setBackIndicatorImage:[UIImage imageNamed:@"navibar_back_btn_bg_normal.png"]];
- [self.navigationController.navigationBar setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"navibar_back_btn_bg_normal.png"]];
- UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:nil];
- self.navigationItem.backBarButtonItem = backItem;
这个方法,如果只是适配iOS 7以上,那么,是目前比较好的解决方案了。
特点:
1.实现了自定义图标,可以没有文字,
2.保存了iOS 7以上系统的pop手势返回。
如果要适配iOS 6,那么就要判断系统版本,如果大于iOS 7,就用上面的代码,如果低于iOS 7.0,就用另外的代码(下面在介绍)
效果如下图:
backItem;
2、那么,我们在A视图设置的代码,系统是如何实现从A视图push到B视图后,显示在B视图的?
看图:
显示原理【2】:
1、如果B视图有一个自定义的左侧按钮(leftBarButtonItem),则会显示这个自定义按钮;
2、如果B没有自定义按钮,但是A视图的backBarButtonItem属性有自定义项,则显示这个自定义项;
3、如果前2条都没有,则默认显示一个后退按钮,后退按钮的标题是A视图的标题。
3、如果理解了第2点,那么怎样自定义代码,才能适配iOS 6和iOS 7以上呢?
自定义要求:
1.自定义图标,文字可要可不要。
2.对于iOS 7以上,保留pop手势.
分析:如果在A视图自定义了返回按钮,又要适配iOS6 ,但由于iOS6 下没有手势返回,所以只能点击左上角返回,怎么处理?
直接上答案:
方案一【3】:
在A视图中:
- if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) //如果系统版本在iOS 7.0以上,执行
- {
- [self.navigationController.navigationBar setBackIndicatorImage:[UIImage imageNamed:@"name="navibar_back_btn_bg_normal.png"]];
- [self.navigationController.navigationBar setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"navibar_back_btn_bg_normal.png"]];
- UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:nil];
- self.navigationItem.backBarButtonItem = backItem;
- }
在B视图中:
- if (SYSTEM_VERSION_LESS_THAN(@"7.0")) //如果系统版本在iOS 7.0以下(不包括7.0),执行
- {
- //导航条返回按钮
- UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
- [button setImage:[UIImage imageNamed:@"navibar_back_btn_bg_normal.png]forState:UIControlStateNormal];
- [button setFrame:CGRectMake(0,0,30,30)">];
- [button addTarget:self action:@selector(jumpBack:) forControlEvents:UIControlEventTouchUpInside];
- UIBarButtonItem * barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
- self.navigationItem.leftBarButtonItem = barButtonItem;
- }
- #pragma mark - 跳转回去
- - (void)jumpBack:(id)sender{
- [self.navigationController popViewControllerAnimated:YES];
- }
方案二:
//在A视图中:
- //开启iOS7的滑动返回效果
- if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
- self.navigationController.interactivePopGestureRecognizer.delegate = nil;
- }
- [self.navigationController pushViewController:registerVC animated:YES];
//在B视图中(ViewDidLoad):
- //导航条返回按钮
- UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
- [button setImage:[UIImage imageNamed:@"navibar_back_btn_bg_normal.png]forState:UIControlStateNormal];
- [button setFrame:CGRectMake(0,0,30,30)];
- [button addTarget:self action:@selector(jumpBack:) forControlEvents:UIControlEventTouchUpInside];
- UIBarButtonItem * barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
- self.navigationItem.leftBarButtonItem = barButtonItem;
- #pragma mark - 跳转回去
- - (void)jumpBack:(id)sender{
- [self.navigationController popViewControllerAnimated:YES];
- }
这个方案,不用适配iOS 6和iOS 7,与方案一区别是,箭头比较靠右边,为什么?说到这个,我下一篇文章在会针对Navigation层次结构在说吧。
方案三:
- - (void)viewWillAppear:(BOOL)animated
- {
- // 注意,这个<span style="font-family: Arial, Helvetica, sans-serif;">interactivePopGestureRecognizer</span><span style="font-family: Arial, Helvetica, sans-serif;">属性是iOS 7才有的</span>
- self.navigationController.interactivePopGestureRecognizer.delegate = self;
- }
- //导航条返回按钮
- UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
- [button setImage:[UIImage imageNamed:@"navibar_back_btn_bg_normal.png"]
- forState:UIControlStateNormal];
- [button setFrame:CGRectMake(0,0,30,30)];
- [button addTarget:self action:@selector(jumpBack:) forControlEvents:UIControlEventTouchUpInside];
- UIBarButtonItem * barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
- self.navigationItem.leftBarButtonItem = barButtonItem;
- #pragma mark - 跳转回去
- - (void)jumpBack:(id)sender{
- [self.navigationController popViewControllerAnimated:YES];
- }
3、自定义几点说明
1.返回文字可以自定义为照片
- UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed: @"navibar_back_btn_bg_normal.png"] style:(UIBarButtonItemStylePlain) target:nil action:nil];
- self.navigationItem.backBarButtonItem = backItem;
看图:
第二个"<",就是自定的图片,这个自定义有意思吗?大家看着用吧
2.自定义视图无效!
- UIView * view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 30, 44)];
- view.backgroundColor = [UIColor colorWithRed:0.263 green:1.000 blue:0.311 alpha:1.000];
- UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:view];
- self.navigationItem.backBarButtonItem = backItem;
3.自定义按钮~
注意这个相对第1个自定义照片的区别:backBarButtonItem不能用View视图方法自定义,而leftBarButtonItem可以哦!
- UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
- [button setImage:[UIImage imageNamed:@"navibar_back_btn_bg_normal.png"] forState:UIControlStateNormal];
- [button setFrame:CGRectMake(0, 0, 30, 44)];
- [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
- UIBarButtonItem * barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
- self.navigationItem.<span style="color:#ff0000;">leftBarButtonItem</span> = barButtonItem;
这个自定义,根据【2】,可以知道其作用,在这里不在多说。
4.pop手势
- //官方文档:
- NS_CLASS_AVAILABLE_IOS(2_0) @interface UINavigationController : UIViewController
- @property(nonatomic, assign) id<UINavigationControllerDelegate> delegate;
- @property(nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0);
以上的方法,都是基于系统自带的UINavigationController来自定义,如果不是系统的,比如淘宝的是自定义的UINavigation,所以没有利用系统的pop手势,而是自定义手势。又比如天猫的只用到【2】的改变图标,但文字都是统一的“返回”,并且部分页面,不用pop手势,直接弹回去。【分析于:2014.11.23日】
最后,大家都试试自定义自己的back按钮吧!如果你有更多更好的自定义方法,记得分享哦!还有很多细节我没有说到,如果大家感兴趣的,可以自己在深入研究一下哦~
4、附录:
【1】关于系统自带的“<”图标的官方解释:
- /*
- The back indicator image is shown beside the back button.
- The back indicator transition mask image is used as a mask for content during push and pop transitions
- Note: These properties must both be set if you want to customize the back indicator image.
- */
- @property(nonatomic,retain) UIImage *backIndicatorImage NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
- @property(nonatomic,retain) UIImage *backIndicatorTransitionMaskImage NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
根据上面文档:
1、只有这两个属性都设置了,才会显示自定义的图片。
2、这两个属性,只能用于iOS 7以上。
3、很多人问为什么要设置“backIndicatorTransitionMaskImage”这个属性,看官方文档就知道,当push、pop时显示的是这张image,但是疑问的是,当我设置这张照片跟“backIndicatorImage”属性的照片不一样时,系统不管是push,还是pop,还是完成时,都只会显示"backIndicatorImage"属性设置的照片。但由于文档没有更多信息,所以,这个问题我也就没有找到答案。
【2】参考一大神的总结:
UINavigationController Class Reference去,在“Updating the Navigation Bar”小节,有这么一段话:
The bar button item on the left side of the navigation bar allows for navigation back to the previous view controller on the navigation stack. The navigation controller updates the left side of the navigation bar as follows:
- If the new top-level view controller has a custom left bar button item, that item is displayed. To specify a custom left bar button item, set the leftBarButtonItem property of the view controller’s navigation item.
- If the top-level view controller does not have a custom left bar button item, but the navigation item of the previous view controller has a valid item in itsbackBarButtonItem property, the navigation bar displays that item.
- If a custom bar button item is not specified by either of the view controllers, a default back button is used and its title is set to the value of the title property of the previous view controller—that is, the view controller one level down on the stack. (If there is only one view controller on the navigation stack, no back button is displayed.)
我大致解释一下,使用pushViewController切换到下一个视图时,navigation controller按照以下3条顺序更改导航栏的左侧按钮。
1、如果B视图有一个自定义的左侧按钮(leftBarButtonItem),则会显示这个自定义按钮;
2、如果B没有自定义按钮,但是A视图的backBarButtonItem属性有自定义项,则显示这个自定义项;
3、如果前2条都没有,则默认显示一个后退按钮,后退按钮的标题是A视图的标题。
【3】关于判断处理说明,和判断系统版本代码
- //检查系统版本
- #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
- #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
- #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
- #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
- #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
官方文档:
- + (UIDevice *)currentDevice;
- @property(nonatomic,readonly,retain) NSString *name; // e.g. "My iPhone"
- @property(nonatomic,readonly,retain) NSString *model; // e.g. @"iPhone", @"iPod touch"
- @property(nonatomic,readonly,retain) NSString *localizedModel; // localized version of model
- @property(nonatomic,readonly,retain) NSString *systemName; // e.g. @"iOS"
- @property(nonatomic,readonly,retain) NSString *systemVersion; // e.g. @"4.0"
- @property(nonatomic,readonly) UIDeviceOrientation orientation; // return current device orientation. this will return UIDeviceOrientationUnknown unless device orientation notifications are being generated.
- @property(nonatomic,readonly,retain) NSUUID *identifierForVendor NS_AVAILABLE_IOS(6_0); // a UUID that may be used to uniquely identify the device, same across apps from a single vendor.
nice~
【转】自定义iOS的Back按钮(backBarButtonItem)和pop交互手势(interactivepopgesturerecognizer) --- 不错的更多相关文章
- iOS7自定义back按钮和pop交互手势
Clambake for iPhone有一个回退按钮在所有的导航条上.这是一个简单的没有文字箭头. 实现一个自定义按钮是简单的.类似这个设置controller 的navigationItem一个le ...
- iOS 添加导航按钮
iOS设置导航按钮navigationBar中包含了这几个重要组成部分:leftBarButtonItem, rightBarButtonItem, backBarButtonItem, title. ...
- iOS8自定义推送显示按钮及推送优化
http://www.jianshu.com/p/803bfaae989e iOS8自定义推送显示按钮及推送优化 字数1435 阅读473 评论0 喜欢2 导语 在iOS8中,推送消息不再只是简单地点 ...
- 解决 ios7.0 以后自定义导航栏左边按钮靠右的问题
解决 ios7.0 以后自定义导航栏左边按钮靠右的问题 www.111cn.net 编辑:edit02_lz 来源:转载 最近开发了一个ios的app,在ios7.0+出现自定义导航栏左边按钮出现靠右 ...
- UIBarButtonItem-添加自定义Left或者Right按钮
为UINavigationController添加UINavigationItem,我们可以这样写: 1.添加返回导航按钮backBarButtonItem 1.用系统自带的返回按钮 UIBa ...
- UIBarButtonItem-添加自定义Left或者Right按钮 <总结>
为UINavigationController添加UINavigationItem 1.添加返回导航按钮backBarButtonItem 1.用系统自带的返回按钮 UIBarButtonIt ...
- 微信小程序 修改(自定义) 单选/复选按钮样式 checkbox/radio样式自定义
参考文章: 微信小程序 修改(自定义) 单选/复选按钮样式 checkbox/radio样式自定义
- 自定义jQuery Mobile工具栏按钮
自定义jQuery Mobile工具栏按钮 1.实现效果
- Apple iOS 触控按钮 自动关闭 bug
Apple iOS 触控按钮 自动关闭 bug bug 轻点 iPhone 背面可执行操作 您可以轻点两下或轻点三下 iPhone 背面以执行某些操作,如向上或向下滚动.截屏.打开"控制中心 ...
随机推荐
- websphere变成英文了怎么变回中文
今天进来发现,websphere在浏览器里面居然是英文的.这是因为我的浏览器少了一个中文语言设置,其实和页面编码无关. 解决办法: IE浏览器右键属性 -- internet选项 -- 常规 -- ...
- hdu 4869
一个机智题,可惜比赛的时候没有机智出来 #include<cstdio> #include<cstring> #include<cmath> #include< ...
- uva 514
栈的简单应用 /************************************************************************* > Author: xlc28 ...
- android 解析XML方式(二)
上一节中,我们使用DOM方式解析xml文档,该方式比较符合我们日常思维方式,容易上手,但是它直接把文档调入内存中,比较耗内存.在这里我们可以用另外一种方式解析xml,这个就是SAX方式. SAX即是: ...
- Nagios 安装及微信短信提醒
引言 Nagios 作为业界非常强大的一款开源监视系统. 监控网络服务(SMTP.POP3.HTTP.NNTP.PING 等): 监控主机资源(处理器负荷.磁盘利用率等): 简单地插件设计使得用户可以 ...
- POJ 2568/ZOJ 1965 Decode the Tree
题意:在树中,每次删去节点值最小的叶子结点. 每删去一个点,就给出与这相连的点的值,直到最后只剩下一个根结点,给这N-1个数,重新建立这个树. 思路: 给出的节点号按次序存入到数组a中,将未给出的数存 ...
- [SQL Server 系] -- 模糊查询
SQL Server中的通配符有下面四种 通配符 说明 % 包含零个或多个字符的任意字符串 _(下划线) 任意单个字符 [ ] 任意在指定范围或集合中的单个字符 [^ ] 任意不在指定范围或集合中的单 ...
- Happy Number
https://leetcode.com/problems/happy-number/ Write an algorithm to determine if a number is "hap ...
- BZOJ 1982 Moving Pebbles
首先我们假设只有两堆, 容易发现当且仅当两堆相等时,先手必败 否则先手必胜 然后我们猜测一下原因: ->当两堆相等时,无论先手怎么做,后手总能使两堆相等,且必败态为0,0 推广一下: 当所有的石 ...
- 【Linux高频命令专题(5)】rmdir
简述 rmdir是常用的命令,该命令的功能是删除空目录,一个目录被删除之前必须是空的.(注意,rm - r dir命令可代替rmdir,但是有很大危险性.)删除某目录时也必须具有对父目录的写权限. 命 ...