iOS 導(dǎo)航欄-返回按鈕-自定義

在開發(fā)過程中,我們經(jīng)常遇到使用系統(tǒng)導(dǎo)航欄的功能,如何更改返回按鈕的樣式呢?

一、更改返回按鈕圖片

// 更換返回按鈕的圖片
UIImage *backButtonImage = [[UIImage imageNamed:@"bt_navigationBar_back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
[UINavigationBar appearance].backIndicatorTransitionMaskImage = backButtonImage;
[UINavigationBar appearance].backIndicatorImage = backButtonImage;


// 返回按鈕的文字置空(在UINavigationController的子類或者分類categary)中添加該方法
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item {
    UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    item.backBarButtonItem = back;
    return YES;
}

二、重寫返回按鈕

重寫返回按鈕一般是添加leftBarButtonItems。如果導(dǎo)航欄添加了leftBarButtonItems之后,會(huì)自動(dòng)隱藏返回按鈕backBarButtonItem。

// 返回按鈕
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"bt_navigationBar_back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(backAction)];
self.navigationItem.leftBarButtonItem = backBarButtonItem;

// 返回按鈕的回調(diào)方法
- (void)backAction {
}

三、攔截系統(tǒng)導(dǎo)航欄的返回按鈕監(jiān)聽事件

當(dāng)我們使用了系統(tǒng)的導(dǎo)航欄時(shí),默認(rèn)點(diǎn)擊返回按鈕是 pop 回上一個(gè)界面。但是在有時(shí)候,我們需要在點(diǎn)擊導(dǎo)航欄的返回按鈕時(shí)不一定要 pop 回上一界面,可能是其他的頁面,我們需要攔截返回按鈕的pop操作。

1、重寫返回按鈕
具體操作查看上面“二、重寫返回按鈕”。
缺點(diǎn):若重寫了某個(gè)界面的返回按鈕,感覺應(yīng)用整體就不統(tǒng)一了。而且每有一個(gè)界面有這個(gè)需求都需要重新自定義一個(gè)返回按鈕,顯得不優(yōu)雅,工作繁瑣。

2、為 UINavigationController 添加 category

//item將要push的時(shí)候調(diào)用,返回NO,則不能push
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item; // called to push. return NO not to.

//item已經(jīng)push后調(diào)用
- (void)navigationBar:(UINavigationBar *)navigationBar didPushItem:(UINavigationItem *)item;    // called at end of animation of push or immediately if not animated

//item將要pop時(shí)調(diào)用,返回NO,不能pop  
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;  // same as push methods

//item已經(jīng)pop后調(diào)用 
- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;

我們可以為 UINavigatonController 創(chuàng)建一個(gè) Category,來定制navigationBar: shouldPopItem: 的邏輯。

// UIViewController+BackButtonHandler.h
@protocol BackButtonHandlerProtocol <NSObject>
@optional
// 重寫下面的方法以攔截導(dǎo)航欄返回按鈕點(diǎn)擊事件,返回 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 后,復(fù)原返回按鈕的狀態(tài)
        for(UIView *subview in [navigationBar subviews]) {
            if(0. < subview.alpha && subview.alpha < 1.) {
                [UIView animateWithDuration:.25 animations:^{
                    subview.alpha = 1.;
                }];
            }
        }
    }
    return NO;
}

使用時(shí),只需要在需要攔截返回按鈕事件的控制器中,應(yīng)用#import "UIViewController+BackButtonHandler.h",并重寫-(BOOL)navigationShouldPopOnBackButton方法即可。

- (BOOL)navigationShouldPopOnBackButton{
   //攔截返回按鈕后做的處理

    //返回NO(一定要返回NO)
    return NO;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 當(dāng)我們使用了系統(tǒng)的導(dǎo)航欄時(shí),默認(rèn)點(diǎn)擊返回按鈕是 pop 回上一個(gè)界面。但是在有時(shí)候,我們需要在點(diǎn)擊導(dǎo)航欄的返回按鈕...
    乒什么乓閱讀 40,762評論 29 76
  • 更新:最后提供的所謂“終極”解決方案,之前都是自己的項(xiàng)目在用,分享出來之后,發(fā)現(xiàn)有一些地方還需要改進(jìn)。但是總體思路...
    _奔跑的炸雞閱讀 40,350評論 124 657
  • 今天下午媽媽給我買了一把美麗的雨傘,我真是喜歡極了。 雨傘上面有著小狗的腳印,有一只小花貓,頭上戴著一...
    屈炫宇閱讀 119評論 0 0
  • 關(guān)于戰(zhàn)斗力,先分享一句話:總是戰(zhàn)斗力滿格、雞血爆棚是有病的!這個(gè)說法,就來自經(jīng)常被朋友們評價(jià)正能量滿滿的我。 經(jīng)常...
    千尋喵閱讀 1,149評論 0 3
  • 上學(xué)第一周周末,沒有出門計(jì)劃也沒任何課外班要去,同時(shí)打算這學(xué)期不再有周末出行計(jì)劃和課外班,剛搬到這一切都不...
    向往清靈閱讀 408評論 0 6

友情鏈接更多精彩內(nèi)容