今天在做項目的時候遇到一點小問題,后來自己解決了,也順便思考了一下更深層次的東西,在這里分享一下~~
替換返回按鈕的文字
很多app的要求所有的返回按鈕的title都是“返回”,如果上一層題目文字太多,下一層的返回按鈕文字就會顯示不完全,而且這樣可以使軟件顯得整潔。
方法一:
最普通的想法,A界面的navigationItem.backBarButtonItem修改的是B(A的下一級)界面的返回按鈕,所以可以寫一個BaseViewController
,讓所有的UIViewController
繼承它,像這樣
- (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil]; }
方法二:
思路是:在開啟程序時,使用Method Swizzling
,將系統自帶的backBarButtonItem
方法替換成我們自定義的方法。
具體實現就是創建個 UINavigationItem + BackItem
的類別,當系統執行+load
方法時,將backBarButtonItem
方法和myCustomBackButton
方法交換,利用iOS關聯方法(objc_getAssociatedObject,objc_setAssociatedObject)
在static
區創建個backItemButton
用來展示。這個方法的好處就是將類別導入到工程里不用任何代碼就可以實現,上代碼吧:
+(void)load{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method originalMethodImp = class_getInstanceMethod(self, @selector(backBarButtonItem)); Method destMethodImp = class_getInstanceMethod(self, @selector(myCustomBackButton)); method_exchangeImplementations(originalMethodImp, destMethodImp); }); } static char kCustomBackButtonKey; -(UIBarButtonItem *)myCustomBackButton{ UIBarButtonItem *item = [self myCustomBackButton]; if (item) { return item; } item = objc_getAssociatedObject(self, &kCustomBackButtonKey); if (!item) { item = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:NULL]; objc_setAssociatedObject(self, &kCustomBackButtonKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } return item; } - (void)dealloc { objc_removeAssociatedObjects(self); }
返回按鈕只顯示自定義圖片
方法一:
最開始我的方案是實現UINavigationController
的代理判斷是否是棧底,如果不是就修改leftBarButtonItem
的樣式。
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { UIViewController *root = navigationController.viewControllers[0]; if (root != viewController) { UIBarButtonItem *itemleft = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"backBtn"] style:UIBarButtonItemStylePlain target:self action:@selector(popAction:)]; viewController.navigationItem.leftBarButtonItem = itemleft; } } - (void)popAction:(UIBarButtonItem *)barButtonItem { [self.navigationController popViewControllerAnimated:YES]; }
但iOS7.0
出了之后,這並不是一個好的解決方案。因為iOS7.0
之后如果把backItemButton
替換成leftItemButon
,interactivePopGestureRecognizer
手勢就沒有了。雖然可以使用
self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
方法二:
這個方法和上邊‘替換返回按鈕的文字’方法二大致一樣,這句話要替換:
item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back"] style:UIBarButtonItemStylePlain target:nil action:nil];
這句話要加上,用來去除系統自帶的返回按鈕上的尖腳號。
[[UINavigationBar appearance] setBackIndicatorImage:[[UIImage alloc]init]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[[UIImage alloc] init]];
技術上的問題其實有好多方法可以去解決,而且在效率相差不大的情況下,關鍵是我們的使用習慣,所以整理一下現在的思路,方便以后使用。