截取iOS系統返回事件

來源:互聯網
上載者:User

標籤:and   show   animate   view   end   hup   美的   pat   state   

當我們使用了系統的導覽列時,預設點擊返回按鈕是 pop 回上一個介面。但是在有時候,我們需要在點擊導覽列的返回按鈕時不一定要 pop 回上一介面,比如一個視頻播放介面,進入橫屏後,預設點擊返回按鈕仍然是 pop 返回上一個介面,但是如果我們想要在橫屏點擊返回按鈕的時候是返回豎屏模式,而不是 pop 到上一介面,這該怎麼實現呢?注意:我們要的不是擷取點擊返回按鈕的時機,而是想要攔截點擊返回按鈕的 pop 操作,使我們可以進行選擇性的 pop,而不是必然的 pop。下面一步步來解決這個問題。一、自訂返回按鈕第一種,自訂導覽列的返回按鈕,雖然這看起來是一種方式,但是也不能從根本上解決;比如整個應用的返回鍵都是統一的,這時候再重寫了某個介面的返回按鈕感覺就不統一了。而且每有一個介面有這個需求都需要重新自訂一個返回按鈕,顯得不優雅。自訂返回按鈕的方法很簡單,如下:// 自訂返回按鈕- (void)customBackButton{    UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];    [backBtn setTitle:@"返回" forState:UIControlStateNormal];    [backBtn addTarget:self action:@selector(backBtnClicked:) forControlEvents:UIControlEventTouchUpInside];    backBtn.frame = CGRectMake(0, 0, 60, 40);    [backBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];    UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithCustomView:backBtn];    self.navigationItem.leftBarButtonItem = item;}// 返回按鈕按下- (void)backBtnClicked:(UIButton *)sender{    if (_isLandscape) {        // 進入豎屏        [self enterPortrait];           return;    }    // pop    [self.navigationController popViewControllerAnimated:YES];}二、為 UINavigationController 添加 category    此方法來自 github:UIViewController-BackButtonHandler由於系統的 UINavigationController 使用了一個 UINavigationBar 來管理 Controller 的 pop 和 push 等操作,所以仔細查看 UINavigationBar 的 API,會發現一個 UINavigationBarDelegate,它包含了四個方法:- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item; // called to push. return NO not to.- (void)navigationBar:(UINavigationBar *)navigationBar didPushItem:(UINavigationItem *)item;    // called at end of animation of push or immediately if not animated- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;  // same as push methods- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;我們會驚喜的第一個不就是我們想要的效果嗎?因為該方法返回 YES 則 pop,若返回NO,則不POP。因此我們可以為 UINavigatonController 建立一個 Category,來定製navigationBar: shouldPopItem: 的邏輯。這裡需要注意的是,我們不需要去設定 delegate,因為 UINavigatonController 內建的 UINavigationBar 的 delegate 就是導覽列本身。這樣還有個問題就是,那在實際的 Controller 裡面怎麼控制呢?因此同樣需要對 UIViewController 添加一個 Protocol,這樣在 Controller 中使用該 Protocol 提供的方法即可進行控制了,代碼如下:// UIViewController+BackButtonHandler.h@protocol BackButtonHandlerProtocol <NSObject>@optional// 重寫下面的方法以攔截導覽列返回按鈕點擊事件,返回 YES 則 pop,NO 則不 pop-(BOOL)navigationShouldPopOnBackButton;@end@interface UIViewController (BackButtonHandler) <BackButtonHandlerProtocol>@end// UIViewController+BackButtonHandler.m @implementation UIViewController (BackButtonHandler)@end@implementation UINavigationController (ShouldPopOnBackButton)- (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 {        // 取消 pop 後,複原返回按鈕的狀態        for(UIView *subview in [navigationBar subviews]) {            if(0. < subview.alpha && subview.alpha < 1.) {                [UIView animateWithDuration:.25 animations:^{                    subview.alpha = 1.;                }];            }        }    }    return NO;}到這兒,幾乎就完美的解決一開始的問題了,使用方法也非常簡單(1). 在一個 Controller 中:#import "UIViewController+BackButtonHandler.h"(2). 重寫 navigationShouldPopOnBackButton 方法- (BOOL)navigationShouldPopOnBackButton{    [[[UIAlertView alloc] initWithTitle:@"提示" message:@"確定返回上一介面?"                               delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil] show];    return NO;}// UIAlertViewDelegate- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex{    if (buttonIndex==1) {        [self.navigationController popViewControllerAnimated:YES];    }}

 

截取iOS系統返回事件

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.