[iOS]自定義NavigationController的一般過程
在專案中,我們經常會使用UINavigationController來管理一組控制器,但是,如果我們使用系統自帶的NavigationController,可能會造成許多意想不到的問題,比如說返回手勢的失效,NavigationBar顏色設定的不一致(由於透明度造成),或者是當NavigationController巢狀在UITabbarController中使用時,在push過程中,tabor何時消失的不確定等等問題,所以我們經常使用自定義的NavigationController來控制一組控制器,過程如下:
- 1.繼承UINavigationController來實現自己的NavigationController。
- 2.解決返回手勢失敗的問題。
- 3.解決NavigationBar顏色設定不一致的問題。
- 4.解決push時隱藏Tabbar。
- 5.設定整個NavigationController狀態列的樣式,注意:在iOS7之後,修改狀態列樣式的方法不被提供了,而是改為了控制器自己重寫方法
- (UIStatusBarStyle)preferredStatusBarStyle;
來實現。但是如果控制器被NavigationController所管理,那麼該方法只會呼叫一次,即呼叫棧底層的控制器的該方法,其他控制器的該方法會被截斷。
首先先說第一點,這一個很簡單,直接建立一個繼承自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
第二點:解決返回手勢失效的問題
我們可以定義一個屬性來儲存NavigationController的interactivePopGestureRecognizer的delegate來解決該問題,程式碼如下:
@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
第三點:解決NavigationBar顏色設定不一致的問題,該問題主要是因為NavigationBar有透明度導致的,下面程式碼的方法比較實用:
@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
然後在合適位置設定顏色即可:
- (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];
}
第四點:解決push時隱藏Tabbar,這個就比較簡單了,程式碼如下:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.viewControllers.count > 0) {
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
第五點:設定狀態列樣式,程式碼如下:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
最後,我們可以根據需求進行一些通用設定,比如設定通用返回按鈕:
- (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];
}
這樣下來,我們就完成了一個比較實用的自定義的NavigationController的設定了,然後去自己的專案中使用吧。
相關文章
- MySQL使用之五_自定義函式和自定義過程MySql函式
- 自定義msi安裝包的執行過程
- iOS自定義的PickViewiOSView
- Swift iOS : NavigationControllerSwiftiOSNavigationController
- MySQL自定義函式與儲存過程MySql函式儲存過程
- 案例展示自定義C函式的實現過程函式
- iOS自定義tabBariOStabBar
- (9)mysql 中的儲存過程和自定義函式MySql儲存過程函式
- oracle自定義過程來獲得完整的sql語句OracleSQL
- 自定義效能統計儲存過程包runstats儲存過程
- iOS 自定義 UISlider 的 trackRectiOSUIIDE
- iOS-自定義PickerViewiOSView
- VS2010自定義模版全過程
- 自定義右鍵選單實現過程詳解
- iOS 自定義內容的彈窗iOS
- 深入mysql建立自定義函式與儲存過程的詳解MySql函式儲存過程
- iOS自定義UIView動畫效果iOSUIView動畫
- iOS自定義UIPageControliOSUI
- iOS 自定義進度條iOS
- 08.Django自定義模板,自定義標籤和自定義過濾器Django過濾器
- 自定義過渡動畫動畫
- java呼叫oracle儲存過程的自定義型別(可變陣列)JavaOracle儲存過程型別陣列
- 自定義show_space過程來顯示資料段的利用資訊
- 我的MYSQL學習心得(10) : 自定義儲存過程和函式MySql儲存過程函式
- Android自定義日曆控制元件的實現過程詳解Android控制元件
- 【iOS】關於 UICollectionView 的自定義佈局iOSUIView
- iOS main()執行前的過程 + weak 置 nil的過程iOSAI
- angular中的自定義過濾器Angular過濾器
- iOS探索 KVO原理及自定義iOS
- iOS探索 KVC原理及自定義iOS
- iOS自定義控制元件 AlertViewiOS控制元件View
- iOS自定義控制元件 SegmentiOS控制元件
- ios自定義圓環進度條iOS
- iOS自定義 Transitions 動畫總結iOS動畫
- iOS 自定義 AlertController 分享iOSController
- iOS使用xib自定義UIViewiOSUIView
- IOS:修改NavigationController的後退按鈕標題iOSNavigationController
- Android專案實戰 ProgressDialog自定義和封裝過程Android封裝