UINavigationController 默認(rèn)返回按鈕 處理

之前寫過(guò)一個(gè)處理這個(gè)玩意兒的文章,主要是設(shè)置返回按鈕的文字和圖片,今天介紹一個(gè)新做法,幾個(gè)api自行谷歌,我就直接上代碼了

為了方便,定義兩個(gè)類型

typedef void(^PushBlock)(UINavigationController* self, UIViewController* viewController, BOOL animated);
typedef void(*PushIMP)(id, SEL, UIViewController*, BOOL);

定義一個(gè)攔截函數(shù)(私有)

/**
 攔截 -[UINavigationController pushViewController:animated:]

 @param push block代碼塊
 */
static void intercept_push(PushBlock push)
{
    static PushBlock will_push;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class nvc_class = [UINavigationController class];
        SEL push_sel = @selector(pushViewController:animated:);
        Method push_method = class_getInstanceMethod(nvc_class, push_sel);
        PushIMP push_imp = (PushIMP)method_getImplementation(push_method);
        IMP push_block = imp_implementationWithBlock(^(UINavigationController* self, UIViewController* viewController, BOOL animated) {
            if (will_push) {
                will_push(self, viewController, animated);
            }
            push_imp(self, push_sel, viewController, animated);
        });
        class_replaceMethod(nvc_class, push_sel, push_block, method_getTypeEncoding(push_method));
    });
    will_push = push;
}

定義一個(gè)設(shè)置函數(shù)(公開(kāi))

/**
 設(shè)置UINavigationController默認(rèn)返回按鈕內(nèi)容

 @param image nil時(shí)為默認(rèn)
 @param title nil時(shí)為默認(rèn)
 */
void set_nvc_default_back(UIImage* image, NSString* title)
{
    static NSString* back_title;
    static PushBlock will_push = ^(UINavigationController* self, UIViewController* viewController, BOOL animated) {
        self.viewControllers.lastObject.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:back_title style:UIBarButtonItemStylePlain target:nil action:nil];
    };
    back_title = title;
    intercept_push(back_title?will_push:nil);
    [[UINavigationBar appearance] setBackIndicatorImage:image];
    [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:image];
}

下邊是使用方式

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    set_nvc_default_back(nil, @"返回");
    
    return YES;
}

然后,既然做了全局處理,就想著是不是讓這玩意能夠讓指定界面進(jìn)行定制,用了個(gè)簡(jiǎn)單的辦法,如下
定制一個(gè)協(xié)議

/**
 執(zhí)行 set_nvc_default_back 后有效
 */
@protocol NavigationBackContentProtocol
-(NSString*)navigationBackItemTitle;
@end

然后修改 set_nvc_default_back 為

void set_nvc_default_back(UIImage* image, NSString* title)
{
    static NSString* back_title;
    static PushBlock will_push = ^(UINavigationController* self, UIViewController* viewController, BOOL animated) {
        NSString* title = back_title;
        if ([viewController conformsToProtocol:@protocol(NavigationBackContentProtocol)])
        {
            BCPViewController* vc = (BCPViewController*)viewController;
            title = [vc navigationBackItemTitle];
        }
        self.viewControllers.lastObject.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:nil action:nil];
    };
    back_title = title;
    intercept_push(will_push);
    [[UINavigationBar appearance] setBackIndicatorImage:image];
    [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:image];
}

補(bǔ)充:BCPViewController 是個(gè)類型

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

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

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