在項(xiàng)目中,我們經(jīng)常會(huì)使用UINavigationController來(lái)管理一組控制器辕漂,但是反肋,如果我們使用系統(tǒng)自帶的NavigationController,可能會(huì)造成許多意想不到的問(wèn)題跃惫,比如說(shuō)返回手勢(shì)的失效,NavigationBar顏色設(shè)置的不一致(由于透明度造成)艾栋,或者是當(dāng)NavigationController嵌套在UITabbarController中使用時(shí)爆存,在push過(guò)程中,tabor何時(shí)消失的不確定等等問(wèn)題蝗砾,所以我們經(jīng)常使用自定義的NavigationController來(lái)控制一組控制器先较,過(guò)程如下:
- 1.繼承UINavigationController來(lái)實(shí)現(xiàn)自己的NavigationController。
- 2.解決返回手勢(shì)失敗的問(wèn)題悼粮。
- 3.解決NavigationBar顏色設(shè)置不一致的問(wèn)題闲勺。
- 4.解決push時(shí)隱藏Tabbar。
- 5.設(shè)置整個(gè)NavigationController狀態(tài)欄的樣式扣猫,注意:在iOS7之后菜循,修改狀態(tài)欄樣式的方法不被提供了,而是改為了控制器自己重寫方法
- (UIStatusBarStyle)preferredStatusBarStyle;
來(lái)實(shí)現(xiàn)申尤。但是如果控制器被NavigationController所管理癌幕,那么該方法只會(huì)調(diào)用一次,即調(diào)用棧底層的控制器的該方法瀑凝,其他控制器的該方法會(huì)被截?cái)唷?/p>
首先先說(shuō)第一點(diǎn)序芦,這一個(gè)很簡(jiǎn)單,直接創(chuàng)建一個(gè)繼承自UINavigationController的控制器即可粤咪,例如我的MDMNavigationController谚中。代碼如下:
.h文件
#import <UIKit/UIKit.h>
@interface MDMNavigationController : UINavigationController
@end
.m文件
#import "MDMNavigationController.h"
@interface MDMNavigationController ()
@end
@implementation MDMNavigationController
- (void)viewDidLoad {
[super viewDidLoad];
}
@end
第二點(diǎn):解決返回手勢(shì)失效的問(wèn)題
我們可以定義一個(gè)屬性來(lái)保存NavigationController的interactivePopGestureRecognizer的delegate來(lái)解決該問(wèn)題,代碼如下:
@interface MDMNavigationController ()<UINavigationControllerDelegate>
@property (nonatomic, weak) id PopDelegate;
@end
@implementation MDMNavigationController
- (void)viewDidLoad {
[super viewDidLoad];
self.PopDelegate = self.interactivePopGestureRecognizer.delegate;
self.delegate = self;
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (viewController == self.viewControllers[0]) {
self.interactivePopGestureRecognizer.delegate = self.PopDelegate;
}else{
self.interactivePopGestureRecognizer.delegate = nil;
}
}
@end
第三點(diǎn):解決NavigationBar顏色設(shè)置不一致的問(wèn)題寥枝,該問(wèn)題主要是因?yàn)镹avigationBar有透明度導(dǎo)致的宪塔,下面代碼的方法比較實(shí)用:
@implementation UINavigationBar (BackgroundColor)
static char overlayKey;
- (UIView *)overlay
{ return objc_getAssociatedObject(self, &overlayKey);
}
- (void)setOverlay:(UIView *)overlay{
objc_setAssociatedObject(self, &overlayKey, overlay, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)lt_setBackgroundColor:(UIColor *)backgroundColor
{
if (!self.overlay) {
[self setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
[self setShadowImage:[[UIImage alloc] init]];
self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width, 64)];
self.overlay.userInteractionEnabled = NO;
[self insertSubview:self.overlay atIndex:0];
}
self.overlay.backgroundColor = backgroundColor;
}
@end
然后在合適位置設(shè)置顏色即可:
- (void)viewDidLoad {
[super viewDidLoad];
self.PopDelegate = self.interactivePopGestureRecognizer.delegate;
self.delegate = self;
[self.navigationBar lt_setBackgroundColor:DefaultColorBlue];
[self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName : DefaultColorWhite, NSFontAttributeName : [UIFont boldSystemFontOfSize:20]}];
[self.navigationBar setTintColor:DefaultColorWhite];
}
第四點(diǎn):解決push時(shí)隱藏Tabbar,這個(gè)就比較簡(jiǎn)單了囊拜,代碼如下:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.viewControllers.count > 0) {
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
第五點(diǎn):設(shè)置狀態(tài)欄樣式某筐,代碼如下:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
最后,我們可以根據(jù)需求進(jìn)行一些通用設(shè)置冠跷,比如設(shè)置通用返回按鈕:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(backBarButtonItemAction)];
viewController.navigationItem.backBarButtonItem = backBarButtonItem;
}
- (void)backBarButtonItemAction
{
[self popViewControllerAnimated:YES];
}
這樣下來(lái)南誊,我們就完成了一個(gè)比較實(shí)用的自定義的NavigationController的設(shè)置了身诺,然后去自己的項(xiàng)目中使用吧。