在开发中,我们一般会覆盖系统默认的导航栏上的返回按钮(修改按钮颜色和文字)。
具体做法如下:
// 创建按钮
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:@"返回" forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"navigationButtonReturn"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"navigationButtonReturnClick"] forState:UIControlStateHighlighted];
// 按钮自适应
[button sizeToFit];
// 让按钮的内容往左边偏移10
button.contentEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 0);
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
// 添加监听方法
[button addTarget:self action:@selector(backClick) forControlEvents:UIControlEventTouchUpInside];
// 修改导航栏左边的item
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
创建一个UIButton
,给这个按钮设置图片和标题,然后修改为UIBarButtonItem
。
这样这个返回按钮
就变成了我们想要的样子。
但是这种做法也伴随着一个问题:原本iOS系统的滑动返回功能失效了。
(只能点击 “返回按钮” 返回)
解决:
这个问题的根本是手势失效了。
可能1:手势被清空了
// self是我们自定义的导航控制器
NSLog(@"%@",self.interactivePopGestureRecognizer);
打印结果有手势,手势被清空的可能被排除:
<UIScreenEdgePanGestureRecognizer: 0x7fec5a7198a0; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7fec5a709080>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fec5a727ae0>)>>
可能2:手势代理做了一些事情,导致手势失效
1、控制器时态加载完成设置interactivePopGestureRecognizer的代理为控制本身
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 手势代理
self.interactivePopGestureRecognizer.delegate = self;
}
2、当然在@interface
就要继承代理协议了
@interface NavigationController () <UIGestureRecognizerDelegate>
@end
3、实现相关代理方法
#pragma mark - <UIGestureRecognizerDelegate>
/**
决定是否触发手势
*/
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// 排除根控制器,其他所有子控制器都要触发手势
return self.childViewControllers.count > 1;
}
(这样iOS 7后系统默认的滑动返回功能也有了)
最后贴一下我们这个自定义导航控制的代码:
//
// NavigationController.m
#import "NavigationController.h"
@interface NavigationController () <UIGestureRecognizerDelegate>
@end
@implementation NavigationController
+ (void)load
{
UINavigationBar *navBar = [UINavigationBar appearanceWhenContainedIn:self, nil];
[navBar setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
}
#pragma mark - <UIGestureRecognizerDelegate>
/**
决定是否触发手势
*/
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// 排除根控制器,其他所有子控制器都要触发手势
return self.childViewControllers.count > 1;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 手势代理
self.interactivePopGestureRecognizer.delegate = self;
}
/**
重写导航控制器的push方法
*/
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// 在push之前,统一设计返回按钮
// 只有非根控制才需要设置
if (self.childViewControllers.count > 0) {
// 创建按钮
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:@"返回" forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"navigationButtonReturn"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"navigationButtonReturnClick"] forState:UIControlStateHighlighted];
// 按钮自适应
[button sizeToFit];
// 让按钮的内容往左边偏移10
button.contentEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 0);
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
// 添加监听方法
[button addTarget:self action:@selector(backClick) forControlEvents:UIControlEventTouchUpInside];
// 修改导航栏左边的item
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
// 隐藏tabbar
viewController.hidesBottomBarWhenPushed = YES;
}
// 跳转
// 调用父类
[super pushViewController:viewController animated:animated];
}
- (void)backClick
{
// 导航控制器返回
[self popViewControllerAnimated:YES];
}
@end