iOS:優雅的攔截返回按鈕

背景:有時候我們會遇到需要在用戶點擊返回按鈕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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容