- iPhone UIKit詳解
- 王志剛 王中元 朱蕾編著
- 1799字
- 2019-01-01 07:04:25
3.1 UIViewController與畫面的關系
3.1.1 UIViewController概要
UIViewController在UIKit中主要功能是用于控制畫面的切換,其中的view屬性(UIView類型)管理整個畫面的外觀。
在開發iPhone應用程序時UIViewController是否必不可少呢?顯然不是這樣,在第1章中的Hello World程序中顯然就沒有使用UIViewController,這說明不使用UIViewController也能編寫出iPhone應用程序。第1章的Hello World程序只有一個畫面,我們再考慮擁有兩個畫面的應用程序的情況。例如第一個畫面與Hello World程序的畫面類似,畫面中顯示“Hello World!”,當觸摸畫面下方的按鈕后切換到另外一顯示“您好!”的畫面。其實我們仍然可以通過改變畫面中的控件屬性來實現畫面外觀的切換,例如此時可采取將不需要的控件都隱藏起來的方法。此時仍然不需要UIViewController。
但是,像上述這樣實現畫面外觀的切換,同一個畫面中實際上包含別的畫面的控件,代碼看起來將非常凌亂。如果能將不同外觀的畫面進行整體的切換顯然更合理,UIViewController正是用于實現這種畫面切換方式的,其切換示意圖如圖3-1所示。

圖3-1 UIViewController畫面管理示意圖
圖3-1中分別由兩個UIViewController管理兩個畫面,畫面內容分別為“Hello,World!”及“您好,世界!”,當觸摸“畫面跳轉”按鈕后跳轉到另一畫面中。這是一個最簡單的畫面跳轉實例,事先必須將兩個畫面內容(UIView及其子元素)追加到UIWindow對象中,但顯示時只顯示其中一個畫面。具體實例代碼下一小節中有詳細介紹。
3.1.2 UIViewController的切換
本節我們實際使用UIViewController來創建畫面。以第1章“Hello World!”實例為基礎,我們再創建一個新的畫面上面顯示中文“您好、世界!”,并在這兩個畫面間實現自由切換。
不過大家需要注意的是,這里實現的畫面跳轉(或稱切換)方法并非最佳的跳轉方法,目的不過是讓讀者了解UIViewController管理畫面的方式,理解以UIViewController為單位切換畫面的樣子,如圖3-1所示。
本實例中有兩個畫面,第一個畫面中顯示“Hello,World!”,背景為白色,下方布置有一個“畫面跳轉”按鈕。第二個畫面中顯示“您好、世界!”,背景為黑色,下方也布置有一個“畫面跳轉”按鈕。當觸摸“畫面跳轉”按鈕時,可在兩個畫面間進行顯示切換。兩個畫面的代碼如下。
[ViewController1.h] #import <UIKit/UIKit.h> @interface ViewController1 :UIViewController @end [ViewController1.m] #import "ViewController1.h" @implementation ViewController1 -(void)viewDidLoad { [super viewDidLoad]; // 追加“Hello,world!”標簽 // 背景為白色、文字為黑色 UILabel* label = [[[UILabel alloc] initWithFrame:self.view.bounds] autorelease]; label.text = @"Hello,world!"; label.textAlignment = UITextAlignmentCenter; label.backgroundColor = [UIColor whiteColor]; label.textColor = [UIColor blackColor]; label.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIVie wAutoresizingFlexibleHeight; [self.view addSubview:label]; // 追加按鈕 // 單擊按鈕后跳轉到其他畫面 UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setTitle:@"畫面跳轉" forState:UIControlStateNormal]; [button sizeToFit]; CGPoint newPoint = self.view.center; newPoint.y += 50; button.center = newPoint; button.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexib leBottomMargin; [button addTarget:self action:@selector(buttonDidPush) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; } -(void)buttonDidPush { // 自己移向背面 // 結果是ViewController2顯示在前 [self.view.window sendSubviewToBack:self.view]; } @end [ViewController2.h] #import <UIKit/UIKit.h> @interface ViewController2 :UIViewController @end [ViewController2.m] #import "ViewController2.h" @implementation ViewController2 -(void)viewDidLoad { [super viewDidLoad]; // 追加“您好、世界!”標簽 // 背景為黑色、文字為白色 UILabel* label = [[[UILabel alloc] initWithFrame:self.view.bounds] autorelease]; label.text = @"您好、世界!"; label.textAlignment = UITextAlignmentCenter; label.backgroundColor = [UIColor blackColor]; label.textColor = [UIColor whiteColor]; label.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIVie wAutoresizingFlexibleHeight; [self.view addSubview:label]; // 追加按鈕 // 單擊按鈕后畫面跳轉 UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setTitle:@"畫面跳轉" forState:UIControlStateNormal]; [button sizeToFit]; CGPoint newPoint = self.view.center; newPoint.y += 50; button.center = newPoint;button.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexib leBottomMargin; [button addTarget:self action:@selector(buttonDidPush) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; } -(void)buttonDidPush { // 自己移向背面 // 結果是ViewController1顯示在前 [self.view.window sendSubviewToBack:self.view]; } @end
ViewController1與ViewController2都是繼承UIViewController的子類。為了追加畫面控件(UIView及其子類)需要重寫(Overwrite)viewDidLoad方法,其中分別創建標簽與按鈕,并通過addSubview:方法追加到畫面(self.view)中。viewDidLoad方法在UIViewController擁有的UIView(畫面基礎UIView)被導入后調用。此UIView可通過UIViewController的view屬性參照,控件追加到畫面中的代碼如下所示。
[self.view addSubview:控件實例];
另一個重要的知識是,觸摸按鈕后實現畫面切換。首先調用addTarget:action:forControlEvents:方法設置按鈕被觸摸時的響應方法buttonDidPush,關于按鈕等控件的響應事件的設置第4.2節(UIButton)將進行介紹。buttonDidPush方法中只有如下一行代碼,實現畫面的切換。
[self.view.window sendSubviewToBack:self.view];
作為UIWindow的子元素,UIView可以通過其Window屬性參照UIWindow(通常應用程序只有唯一的UIWindow)。這行代碼的作用是“將畫面自己隱藏到背面去”,因為原來UIWindow中包含有兩個畫面,當前畫面隱藏到背面后,另一個畫面就會顯示在前面。
至于將兩個畫面(UIView)追加到UIWindow中的處理在HelloWorldAppDelegate類中實現,以下是HelloWorldAppDelegate的詳細代碼,黑體字部分表示向UIWindow中追加兩個畫面。
[HelloWorldAppDelegate.h] #import <UIKit/UIKit.h> @interface HelloWorldAppDelegate :NSObject <UIApplicationDelegate> { UIWindow*window_; UIViewController*viewController1_; UIViewController*viewController2_; } @property(nonatomic,retain)UIWindow*window; @end [HelloWorldAppDelegate.m] #import "HelloWorldAppDelegate.h" #import "ViewController1.h" #import "ViewController2.h" @implementation HelloWorldAppDelegate @synthesize window = window_; -(void)applicationDidFinishLaunching:(UIApplication *)application { // 初始化Window CGRect bounds = [[UIScreen mainScreen] bounds]; window_ = [[UIWindow alloc] initWithFrame:bounds]; // 創建ViewController1與ViewController2 // 并將其畫面(view)追加到Window中 viewController1_ = [[ViewController1 alloc] init]; viewController2_ = [[ViewController2 alloc] init]; [window_ addSubview:viewController1_.view]; [window_ addSubview:viewController2_.view]; // ViewController1放在前面顯示 [window_ bringSubviewToFront:viewController1_.view]; [window_ makeKeyAndVisible]; } -(void)dealloc { [viewController1_ release]; [viewController2_ release]; [window_ release]; [super dealloc]; } @end
在應用程序初始化applicationDidFinishLaunching:方法中,首先創建兩個畫面的實例,然后分別追加(使用addSubview:方法)到UIWindow中,最后調用UIWindow的bringSubviewToFront:方法將第一個畫面顯示在前面。
實例運行后的效果如圖3-2所示。

圖3-2 畫面切換實例