之前寫過一個處理這個玩意兒的文章,主要是設(shè)置返回按鈕的文字和圖片柬讨,今天介紹一個新做法崩瓤,幾個api自行谷歌,我就直接上代碼了
為了方便踩官,定義兩個類型
typedef void(^PushBlock)(UINavigationController* self, UIViewController* viewController, BOOL animated);
typedef void(*PushIMP)(id, SEL, UIViewController*, BOOL);
定義一個攔截函數(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;
}
定義一個設(shè)置函數(shù)(公開)
/**
設(shè)置UINavigationController默認(rèn)返回按鈕內(nèi)容
@param image nil時為默認(rèn)
@param title nil時為默認(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)行定制蔗牡,用了個簡單的辦法颖系,如下
定制一個協(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 是個類型
typedef UIViewController<NavigationBackContentProtocol> BCPViewController;