UIViewController的分類(BackButtonHandler)攔截返回按鈕的響應(yīng)事件

思路及效果:

利用runtime實(shí)現(xiàn)方法交換(method_exchangeImplementations)和利用runtime 給分類動(dòng)態(tài)綁定屬性kOriginDelegate鉴扫。kOriginDelegate綁定原self.interactivePopGestureRecognizer.delegate代理來響應(yīng)代理方法,添加一個(gè)接口 -(BOOL)navigationShouldPopOnBackButton;供外部訪問澈缺, 這個(gè)接口返回YES正常跳轉(zhuǎn)坪创,返回NO即可攔截返回按鈕的響應(yīng)事件。

具體實(shí)現(xiàn)如下:

UIViewController+BackButtonHandler.h文件:

#import <UIKit/UIKit.h>

@protocol BackButtonHandlerProtocol <NSObject>
@optional
// Override this method in UIViewController derived class to handle 'Back' button click
- (BOOL)navigationShouldPopOnBackButton;
@end

@interface UIViewController (BackButtonHandler) <BackButtonHandlerProtocol>

@end

UIViewController+BackButtonHandler.m文件:

#import "UIViewController+BackButtonHandler.h"
#import <objc/runtime.h>

@implementation UIViewController (BackButtonHandler)

@end

static NSString *const kOriginDelegate = @"kOriginDelegate";

@implementation UINavigationController (ShouldPopOnBackButton)

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        
        SEL originSelector = @selector(viewDidLoad);
        SEL swizzledSelector = @selector(new_viewDidLoad);
        
        Method originMethod = class_getInstanceMethod(class, originSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        BOOL didAddMethod = class_addMethod(class,
                                            originSelector,
                                            method_getImplementation(swizzledMethod),
                                            method_getTypeEncoding(swizzledMethod));
        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originMethod),
                                method_getTypeEncoding(originMethod));
        } else {
            method_exchangeImplementations(originMethod, swizzledMethod);
        }
    });
}

- (void)new_viewDidLoad
{
    [self new_viewDidLoad];
    
    objc_setAssociatedObject(self, [kOriginDelegate UTF8String], self.interactivePopGestureRecognizer.delegate, OBJC_ASSOCIATION_ASSIGN);
    self.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
}

#pragma mark - 按鈕
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
    
    if([self.viewControllers count] < [navigationBar.items count]) {
        return YES;
    }

    BOOL shouldPop = YES;
    UIViewController* vc = [self topViewController];
    if([vc respondsToSelector:@selector(navigationShouldPopOnBackButton)]) {
        shouldPop = [vc navigationShouldPopOnBackButton];
    }

    if(shouldPop) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self popViewControllerAnimated:YES];
        });
    } else {
        for(UIView *subview in [navigationBar subviews]) {
            if(0. < subview.alpha && subview.alpha < 1.) {
                [UIView animateWithDuration:.25 animations:^{
                    subview.alpha = 1.;
                }];
            }
        }
    }
    return NO;
}

#pragma mark - 手勢
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer == self.interactivePopGestureRecognizer) {
        UIViewController *vc = [self topViewController];
        if([vc respondsToSelector:@selector(navigationShouldPopOnBackButton)]) {
            return [vc navigationShouldPopOnBackButton];
        }
        id<UIGestureRecognizerDelegate> originDelegate = objc_getAssociatedObject(self, [kOriginDelegate UTF8String]);
        return [originDelegate gestureRecognizerShouldBegin:gestureRecognizer];
    }
    return YES;
}
@end

使用實(shí)例:

/**
 * 協(xié)議中的方法姐赡,獲取返回按鈕的點(diǎn)擊事件
 */
- (BOOL)navigationShouldPopOnBackButton
{
    if ([self.mark isEqualToString:@"綁定手機(jī)號(hào)"]) {
        UIAlertView *view = [[UIAlertView alloc] initWithTitle:@"" message:@"綁定尚未完成误堡,確認(rèn)退出?" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];
        [view show];
        return NO;
    }else{
        return YES;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雏吭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子陪踩,更是在濱河造成了極大的恐慌杖们,老刑警劉巖悉抵,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異摘完,居然都是意外死亡姥饰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門孝治,熙熙樓的掌柜王于貴愁眉苦臉地迎上來列粪,“玉大人,你說我怎么就攤上這事谈飒∑褡” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵杭措,是天一觀的道長费什。 經(jīng)常有香客問我,道長手素,這世上最難降的妖魔是什么鸳址? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮泉懦,結(jié)果婚禮上稿黍,老公的妹妹穿的比我還像新娘。我一直安慰自己崩哩,他們只是感情好巡球,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著琢锋,像睡著了一般辕漂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吴超,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天钉嘹,我揣著相機(jī)與錄音,去河邊找鬼鲸阻。 笑死跋涣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鸟悴。 我是一名探鬼主播陈辱,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼细诸!你這毒婦竟也來了沛贪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎利赋,沒想到半個(gè)月后水评,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡媚送,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年中燥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塘偎。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疗涉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吟秩,到底是詐尸還是另有隱情咱扣,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布峰尝,位于F島的核電站峡眶,受9級特大地震影響俱恶,放射性物質(zhì)發(fā)生泄漏武契。R本人自食惡果不足惜逊抡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望火窒。 院中可真熱鬧硼补,春花似錦、人聲如沸熏矿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽票编。三九已至褪储,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間慧域,已是汗流浹背鲤竹。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昔榴,地道東北人辛藻。 一個(gè)月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像互订,于是被迫代替她去往敵國和親吱肌。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容