背景:有时候我们会遇到需要在用户点击返回按钮pop之前进行拦截,增加一些业务逻辑,如弹出警告弹框询问用户是否确实要返回等。
实现代码
- 1、创建一个协议MZCustomProtocol
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol MZCustomProtocol <NSObject>
@optional
/// 点击返回按钮的时候, 需要增加额外操作的时候, 在当前控制器里实现该方法
- (void)onClickBackButtonWithAdditionalOperating:(UIBarButtonItem *)backItem;
@end
NS_ASSUME_NONNULL_END
- 2、自定义导航控制器MZBaseNavVC
#import "MZBaseNavVC.h"
#import "MZCustomProtocol.h"
@interface MZBaseNavVC ()<UIGestureRecognizerDelegate>
@end
@implementation MZBaseNavVC
- (void)viewDidLoad {
[super viewDidLoad];
self.interactivePopGestureRecognizer.delegate = self;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
// 实现了指定方法的控制器, 就不允许侧滑返回
if ([self.viewControllers.lastObject respondsToSelector:@selector(onClickBackButtonWithAdditionalOperating:)]) {
return NO;;
}
return self.childViewControllers.count > 1;
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (self.childViewControllers.count > 0) {
UIButton *back = [UIButton buttonWithType:UIButtonTypeCustom];
back.frame = CGRectMake(0, 0, 44, 44);
[back setImage:[UIImage imageNamed:@"back"] forState:UIControlStateNormal];
[back addTarget:self action:@selector(onClickBackButton:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:back];
viewController.navigationItem.leftBarButtonItem = backItem;
self.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
- (void)onClickBackButton:(id)sender {
// 实现了指定方法的控制器, 就走当前控制器里实现的方法
if ([self.viewControllers.lastObject respondsToSelector:@selector(onClickBackButtonWithAdditionalOperating:)]) {
[(id<MZCustomProtocol>)self.viewControllers.lastObject onClickBackButtonWithAdditionalOperating:sender];
} else {
// If the view controller at the top of the stack is the root view controller, this method does nothing.
[self.navigationController popViewControllerAnimated:YES];
}
}
@end
- 3、在需要拦截返回按钮的控制器里,实现对应的方法
onClickBackButtonWithAdditionalOperating:
#import "DetailViewController.h"
#import "MZCustomProtocol.h"
@interface DetailViewController ()<MZCustomProtocol>
@end
@implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
}
- (void)onClickBackButtonWithAdditionalOperating:(UIBarButtonItem *)backItem {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"返回后数据将不保存" preferredStyle:UIAlertControllerStyleAlert];
__weak typeof(self) weakSelf = self;
[alertVC addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:nil]];
[alertVC addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
[weakSelf.navigationController popViewControllerAnimated:YES];
}]];
[self presentViewController:alertVC animated:YES completion:nil];
}
@end