【iOS開發-21】UINavigationController導航控制器初始化,導航控制器棧的push和pop跳轉理解...

weixin_34321977發表於2015-05-01

(1)導航控制器初始化的時候一般都有一個根檢視控制器,導航控制器相當於一個棧,裡面裝的是檢視控制器,最先進去的在最以下,最後進去的在最上面。在最上面的那個檢視控制器的檢視就是這個導航控制器對外展示的介面,也就是使用者看到的介面。


(2)我們須要把導航控制器載入到APP中,須要把這個導航控制器設定為window的根檢視控制器(都是控制器類,能夠賦值),這樣就相當於載入到了window裡。


(3)我們要在棧中新增或者刪除一個檢視控制器,就須要得到導航控制器,一般在棧中得全部檢視控制器都有一個self.navigationController,意思是我的導航控制器,也就是這個檢視控制器所在的導航控制器,這樣就拿到了導航控制器。


(4)棧中新增檢視控制器用pushViewController,事實上就是push進去一個,這樣對於使用者而言就是開啟一個新介面了。


(5)棧中刪除一個檢視控制器用popViewControllerAnimated,當然這個pop僅僅能pop最上面的那個,對於使用者而言相當於從當前檢視回到上一級檢視。


(6)事實上這個push和pop對於使用者而言都是開啟和跳轉頁面的一個操作。而pop由很多其它地操作方法,如一下子pop掉僅僅剩下一個根檢視控制器,那麼就相當於從好幾層直接回到最原始的主頁面。也能夠指定pop幾個,以跳轉到指定的頁面。


(7)最重要的應該就是這個push和pop方法,而pop有非常多種,這個理解後就不難記憶。


(a)AppDelegate.m中,新增以下程式碼:

#import "AppDelegate.h"
//由於要例項化一個物件,須要這個類,所以匯入
#import "ViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //建立一個檢視控制器,以屆時作為導航控制器的根檢視控制器
    ViewController *root1=[[ViewController alloc]init];
    //初始化導航控制器的時候把上面建立的root1初始化給它
    UINavigationController *nav1=[[UINavigationController alloc]initWithRootViewController:root1];
    //最後,我們把window的根檢視控制器設為導航控制器,這樣導航控制器就行顯示在螢幕上
    self.window.rootViewController=nav1;
    // Override point for customization after application launch.
    return YES;
}

@end

(b)在ViewController.m新增下面程式碼:

#import "ViewController.h"
//由於須要例項化一個物件,所以匯入它
#import "SecondViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    //建立一個按鈕,點選後進入子檢視控制器,相當於進入子頁面
    UIButton *btn1=[UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn1.frame=CGRectMake(38, 100, 300, 30);
    [btn1 setTitle:@"jump to secondviewcontroller" forState:UIControlStateNormal];
    btn1.backgroundColor=[UIColor whiteColor];
    self.view.backgroundColor=[UIColor redColor];
    [btn1 addTarget:self action:@selector(jumpTo) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn1];
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

-(void)jumpTo{
    //這裡面核心的有兩個,所謂跳轉,事實上就是往導航控制器棧中PUSH或者POP一個檢視控制器,這樣在最上面的檢視控制器就變了,這樣檢視也跟著變了,由於僅僅顯示在棧頂得那個檢視控制器的檢視
    //所以(1)控制所謂的跳轉,事實上是導航控制器在控制,在裡面的元素都能夠通過navigationController屬性獲取到它們所在的導航控制器
    //所以(2)獲取到導航控制器之後,使用Push的那個方法,往棧裡面放一個檢視控制器senCon1,這個新放入的在棧頂,就顯示它的檢視,所以使用者改變頁面跳轉了
    SecondViewController *senCon1=[[SecondViewController alloc]init];
    [self.navigationController pushViewController:senCon1 animated:YES];
}

@end

(c)在SecondViewController.m中新增下面程式碼:

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    UILabel *label1=[[UILabel alloc]init];
    label1.frame=CGRectMake(38, 80, 300, 30);
    label1.backgroundColor=[UIColor whiteColor];
    label1.text=@"This is secondviewcontroller";
    [self.view addSubview:label1];
    
    UIButton *btn2=[UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn2.frame=CGRectMake(38, 120, 300, 30);
    [btn2 setTitle:@"backTo" forState:UIControlStateNormal];
    btn2.backgroundColor=[UIColor orangeColor];
    [self.view addSubview:btn2];
    [btn2 addTarget:self action:@selector(backTo) forControlEvents:UIControlEventTouchUpInside];
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}
//能夠手動設定pop出棧,相當於刪除這個頁面,跳轉到其它頁面
//popViewControllerAnimated就是彈出,由於彈出僅僅能彈出最上面的棧頂的那個,所以能夠不用指定引數
//popToRootViewControllerAnimated-就是直接跳轉到根檢視控制圖,假設僅僅有兩層,那麼和popViewControllerAnimated並無差別,假設有非常多層,那麼事實上就是相當於不僅把自己pop出去,還把全部除了根檢視控制圖之外的全部檢視控制器都pop出去了,所以就相當於跳轉到根檢視控制器了
//popToViewController-就是跳轉到指定的檢視控制器xxx,這個xxx一定要在這個棧裡面,即一定是在我們當前這個檢視控制器的以下的,所以跳轉也就是把自己和在xxx上面的全部檢視控制器都pop出去,然後相當於直接跳轉到xxx
//此處重點是這個xxx怎麼獲取,依照一般理解是用xxx再初始化一個檢視控制器物件yyy,然後把這個物件yyy作為popToViewController引數
//但事實是,yyy是新初始化的,不在棧中,當然和在棧中的xxx初始化的那個物件也不是同一個物件,所以會報錯(由於在棧中找不到啊)
//所以,self.navigationController.viewControllers出場,viewControllers是個陣列,儲存的時導航控制器棧中全部的檢視控制器,最先push進去的時0,以此類推,最上面的肯定是陣列的最後一個
//所以,那個xxx之前初始化的物件,能夠用[self.navigationController.viewControllers objectAtIndex:0]表示,此處0就是根檢視控制器
//所以,僅僅要拿到navigationController,貌似能做非常多事情
-(void)backTo{
    [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
}

@end

截個圖:


相關文章