您的位置:首页 > 运维架构

自定义导航栏返回按钮点击事件

2017-03-23 14:27 399 查看
开发中经常会遇到 点击导航栏返回按钮时不想 pop 回上一级控制器,而是回到 某一级控制器 或者需要在pop回去的时候回传一些数据,但查看文档发现,系统并没有给我们直接提供这样的方法。

那么我们先来分析如何获取返回按钮的点击事件。

返回按钮在导航栏上,所以我们先找到导航控制器UINavigationController的头文件,他有一个属性

@property(nonatomic,readonly) UINavigationBar *navigationBar;

我们知道返回按钮就在 navigationBar上,在看一下 UINavigationBar 的头文件,我们并没有发现有返回按钮的属性或者返回按钮的点击方法;

但是我们发现 navigationBar 有一个代理属性

@property(nullable,nonatomic,weak) id delegate;

查看 UINavigationBarDelegate 的方法中有一个方法是:

- (BOOL)navigationBar:(UINavigationBar )navigationBar shouldPopItem:(UINavigationItem )item; // same as push methods

哈哈,从方法名上我们已经看出这个方法就是我们要找的了!

由于navigationBar 是NavigationController的属性,我们推测 navigationBar 的 代理就是NavigationController, 于是我就在 NavigationController 里重写了上面那个代理方法,发现在点击返回按钮的时候,确实调用了这个方法,^^ 有没有觉得我们已经接近真相了 O(∩∩)O

等不及啦,直接上代码了

写一个导航控制器的基类

#import <UIKit/UIKit.h>

@interface GZNavigationController : UINavigationController

@end

---------------------------

#import "GZNavigationController.h"
#import "GZViewController.h"

@interface GZNavigationController ()

@end

@implementation GZNavigationController

- (void)viewDidLoad {
[super viewDidLoad];

}

#pragma mark - UINavigationBarDelegate
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;
{
if (self.viewControllers.count > 1) {
GZViewController *topVc = (GZViewController *)self.viewControllers.lastObject;
BOOL isPop = YES;
if ([topVc respondsToSelector:@selector(shouldPopItem)]) {
isPop = [topVc performSelector:@selector(shouldPopItem)];
if (isPop) {
dispatch_async(dispatch_get_main_queue(), ^{
[self popViewControllerAnimated:YES];
});
} else {
//shouldPopItem 方法返回no时发现返回按钮的图标,颜色变淡了,遍历导航栏上的子空间,修改它的透明度为1
for(UIView *subview in [navigationBar subviews]) {
if(subview.alpha < 1.) {
[UIView animateWithDuration:.25 animations:^{
subview.alpha = 1.;
}];
}
}
}
return NO;
}
}
return YES;
}

@end


写一个视图控制器的基类

@interface GZViewController : UIViewController

/**
自定义导航栏返回按钮的点击事件方法

@return 是否返回上一级控制器 ,return YES 返回上一级控制器,如果不想返回上一级控制器,可以重写此方法,处理完自己的逻辑后  return  NO;
*/
- (BOOL) shouldPopItem;

@end

--------------------------

#import "GZViewController.h"

@interface GZViewController ()

@end

@implementation GZViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (BOOL) shouldPopItem
{
//基类中默认 返回YES,也就是pop到上一级控制器
return YES;
}

@end


子类只需要重写 - (BOOL) shouldPopItem 方法,就可以自定义返回按钮的点击事件了。

如有问题,欢迎评论交流!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息