iOS基礎(chǔ)界面就是通過UIViewController展示的。首先區(qū)分content controller和container controller的區(qū)別。content controlller就是展示我們當(dāng)前頁(yè)面的controller,而container controller就是一個(gè)管理content controller的容器,基本就是UINavigationController和UITabbarController,本身它也是繼承UIViewController,一個(gè)UIViewController壓棧就是把它加入到container controller的view上。
下面說一下UIViewController的生命周期:
1. -(void)loadView; 這里用來加載controller的view,一般我們都必須調(diào)用[super loadView]來完成對(duì)view的加載,當(dāng)然如果不需要用self.view也可以。然后再對(duì)我們需要的子view進(jìn)行生成和布局。
2.- (void)viewDidLoad; 這里代表view已經(jīng)加載完成,一般用來處理數(shù)據(jù)model之類的。
3.- (void)viewWillAppear:(BOOL)animated; Controller將要被加入到當(dāng)前window的回調(diào),每次push或pop到當(dāng)前controller就會(huì)回調(diào)這個(gè)函數(shù),代表界面將要展示出來。
4.-(void)viewDidAppear:(BOOL)animated; Controller已經(jīng)被加入到當(dāng)前window,也就是push、present或pop的動(dòng)畫已經(jīng)完成。
{可能被大多數(shù)人忽略的是,在每次調(diào)用viewWillAppear或viewDidAppear,系統(tǒng)都會(huì)調(diào)用一下兩個(gè)函數(shù):
(1)(void)viewWillLayoutSubviews 這個(gè)可能很多人忽略了,是5.0才增加的函數(shù),界面將要對(duì)子view進(jìn)行布局。當(dāng)通話或錄音狀態(tài)中,狀態(tài)欄下移,也會(huì)回調(diào)這個(gè)函數(shù)。
(2)-(void)viewDidLayoutSubviews 這個(gè)跟4對(duì)應(yīng),也是5.0增加的函數(shù),對(duì)子view布局完成。
}
一般在上面4個(gè)函數(shù),我們已經(jīng)可以完成界面的展示。記得它們的先后順序是必須的。至于收到內(nèi)存警告,在6.0等不同版本controller的不同回調(diào)我之前已經(jīng)介紹過了,就不再介紹了。
關(guān)于Container Controller:
這里就只說介紹UINavigationController,本身它就是繼承UIViewController,所以它具有上面所說的生命周期。至于什么東西應(yīng)該放在viewController,什么應(yīng)該放在navgationController呢,這里說說我的理解。
因?yàn)閚avgationController就是管理controller的容器,所以它處理的應(yīng)該就是controller的關(guān)系。并且在某種意義上,它里面的controller就相當(dāng)于它的一個(gè)子view,所以在navgationController的操作就能控制它里面的每個(gè)controller。下面以現(xiàn)在比較流行的手勢(shì)導(dǎo)航為例:(也就是在二級(jí)頁(yè)面向右滑動(dòng)就能返回)
@interface TestNavigationController ()
{
UIPanGestureRecognizer *_panGesture; //手勢(shì)導(dǎo)航的recognizer
CGPoint _panStartPoint; //記錄開始滑動(dòng)的point,只有滑動(dòng)到一定寬度才開啟導(dǎo)航
}
@property(nonatomic,retain)UIPanGestureRecognizer *panGesture;
@end
@implementation TestNavigationController
@synthesize panGesture = _panGesture;
- (void)viewDidLoad
{
[super viewDidLoad];
//在navgationController的view添加手勢(shì),也就是為每個(gè)當(dāng)前的controller添加了手勢(shì)
[self.view removeGestureRecognizer:self.panGesture];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizeralloc] initWithTarget:self
action:@selector(handlePanGesture:)];
panGesture.minimumNumberOfTouches = 1;
panGesture.maximumNumberOfTouches = 1;
panGesture.delegate = self;
self.panGesture = panGesture;
[panGesture release];
[self.view addGestureRecognizer:self.panGesture];
}
-(void)handlePanGesture:(UIPanGestureRecognizer*)pan
{
//記錄開始滑動(dòng)的point
if(pan.state == UIGestureRecognizerStateBegan){
_panStartPoint = [pan locationInView:self.view];
}
//在滑動(dòng)結(jié)束,判斷滑動(dòng)的距離是不是適合寬度,處理是否返回上級(jí)頁(yè)面
if(pan.state == UIGestureRecognizerStateEnded) {
CGPoint _endPoint = [pan locationInView:self.view];
if(_endPoint.x - _panStartPoint.x > 70.0f){
//二級(jí)頁(yè)面就能滑動(dòng)返回
if([self.viewControllers count] > 1){
[self popViewControllerAnimated:YES];
}
}
}
}
#pragma mark UIGestureRecognizerDelegate method //手勢(shì)的delegate,處理一些同時(shí)進(jìn)行的手勢(shì)操作
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
//一般情況下,如果上下滑動(dòng)幅度太大,應(yīng)該就是在滑動(dòng)controller的tableview之類的,就不開啟滑動(dòng)導(dǎo)航
if (gestureRecognizer == self.panGesture) {
CGPoint translation = [(UIPanGestureRecognizer *)gestureRecognizer translationInView:self.view];
return ((fabs(translation.x) / fabs(translation.y) > 5.0f) ? YES : NO);
}
return YES;
}
當(dāng)我們把a(bǔ)ppDelegate的window.rootViewController設(shè)為TestNavigationController,就可以很方便快捷地實(shí)現(xiàn)滑動(dòng)手勢(shì)導(dǎo)航功能。
下面說一下靜態(tài)視圖modelViewController,通常我們就是用
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion壓入一個(gè)模態(tài)視圖。其實(shí)靜態(tài)的概念就是它入棧的方式和動(dòng)畫不同而已。需要注意的是,一個(gè)navgationController不可以push一個(gè)navgationController,但是可以present一個(gè)navgationController。另外,無論是一個(gè)viewController,還是navgationController,都可以present一個(gè)modelViewController,并且modelViewController并不加入到navgationController的導(dǎo)航棧中。
所以navgationController的topViewController和visibleViewController是不同概念的。topViewController就是導(dǎo)航棧stack的棧頂,也就是不包括modelViewController,而visibleViewController是當(dāng)前展示的viewController,如果有模態(tài)視圖就是模態(tài)視圖,否則就是topViewController。
最后用一句話總結(jié), A viewController is a set of views, A navgationcontroller is a set of viewControllers.