當程式中含有多個view,需要在之間切換的時候,可以使用UINavigationController,或者是ModalViewController。UINabigationController 是通過嚮導條來切換多個view。而如果view 的數量比較少,且顯示領域為全屏的時候,用ModalViewController 就比較合適(比如需要使用者輸入資訊的view,結束後自動回複到之前的view)。今天我們就看看ModalViewController 的建立方法。
ModalViewController 並不像UINavigationController 是一個專門的類,使用UIViewController 的presentModalViewController 方法指定之後就是ModalViewController 了。
這裡使用上兩回做成的CustomViewController(由UIViewController繼承)來實現ModalViewController 的執行個體。
首先,準備ModalViewController 退出時的函數。調用UIViewController 的dismissModalViewController:Animated: 方法就可以了,如下所示:
// 這裡按鈕按下的時候退出ModalViewController
-(void)dismiss:(id)inSender {
// 如果是被presentModalViewController 以外的執行個體調用,parentViewController 將是nil,下面的調用無效
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
接下來,產生另一個CustomViewController 的執行個體,用來表示ModalViewController,並將其對應的view 設定成紅色。然後傳遞給presentModalViewController: Animated: 顯示ModalViewController 的view。
- (void)applicationDidFinishLaunching:(UIApplication *)application {
controller = [[CustomViewController alloc] init];
[window addSubview:controller.view];
[window makeKeyAndVisible];
// 產生ModalViewController
CustomViewController* controllerB = [[CustomViewController alloc] init];
// 設定view 的背景為紅色
controllerB.view.backgroundColor = [UIColor redColor];
// 顯示ModalViewController view
[controller presentModalViewController:controllerB animated:YES];
// presentModalViewController 已經被controller 管理,這裡可以釋放該執行個體了
[controllerB release];
}
編譯執行以後,首先啟動的是紅色背景的ModalViewController view、按下按鈕後恢複到藍色背景的通常view 上。
也可以在顯示ModalViewController view 之前設定UIViewContrller 的modalTransitionStyle 屬性,使其以動畫形式顯示。
1
controllerB.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
以上的實現只是單一地實現了ModalViewController view 的功能,除了程式開始提醒使用者一些資訊外什麼也做不了。另外由於是放入了applicationDidFinishLaunching 中的原因,也不能反覆的顯示。另外,在ModalViewController view 上設定的內容也不能反映到原來的view 上。
接下來我們將實現這些功能。
首先,從ModalViewController view 退出的時候,需要通知原先的view。這裡使用iPhone/Cocoa 應用程式中經常使用的Delegate 設計模式(也是推薦使用的)。
實際上,系統所提供的映像選擇控制類UIImagePickerController
或者是參照地址簿時的ABPeoplePickerNavigationController 類,都用到了Delegate 模式。
基於上一講的中的例子,這裡我們追加為3個按鈕,分別是綠色,灰色和取消。
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blueColor];
UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(100,100,100,100);
button.tag = 1;
[button setTitle:@"綠色" forState:UIControlStateNormal];
// 按鈕事件對應函數
[button addTarget:self action:@selector(dismiss:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(100,200,100,100);
button.tag = 2;
[button setTitle:@"灰色" forState:UIControlStateNormal];
// 按鈕事件對應函數
[button addTarget:self action:@selector(dismiss:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(100,300,100,100);
button.tag = 0;
[button setTitle:@"取消" forState:UIControlStateNormal];
// 按鈕事件對應函數
[button addTarget:self action:@selector(dismiss:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
程式啟動的時候依然是先顯示ModalViewController view,按下任何一個按鈕,將關閉該view。按下“綠色”按鈕,設定背景為綠色,按下“灰色”按鈕時,設定背景為灰色。“取消”的時候什麼也不做。
委託處理用下面的函數實現,當參數inColor 為nil 的時候代表取消。
-(void)selectColor:(UIColor*)inColor;
委託代理的執行個體用id 變數表示。
@interface CustomViewController : UIViewController {
id colorSelectDelegate;
}
設定該變數的函數如下。
-(void)setColorSelectDelegate:(id)inDelegate {
colorSelectDelegate = inDelegate;
}
另外如上面viewDidLoad 所示,按鈕的tag 分別為0、1、2。按鈕按下時調用的函數中由不同的tag 來發送不同的UIColor執行個體到colorSelectDelegate 上。
-(void)dismiss:(id)inSender {
UIView* view = (UIView*)inSender;
UIColor* requestColor = nil;
if (view.tag == 1)
requestColor = [UIColor greenColor];
if (view.tag == 2)
requestColor = [UIColor grayColor];
[colorSelectDelegate selectColor:requestColor];
}
這是不使用UIButton* 而是用UIView* ,是因為tag 屬性被定義在UIView 類中,不需要必須轉換為UIButton 類。
另外這樣一來,該函數在UIButton 以外的情況下也能被使用。
如果想檢查id 是什麼類性的可以使用isKindOfClass: 方法。
接收到具體的參數inColor 更換背景色,並關閉ModalViewController view。
-(void)selectColor:(UIColor*)inColor {
if (inColor != nil)
self.view.backgroundColor = inColor;
[self dismissModalViewControllerAnimated:YES];
}
另外,在調用presentModalViewController 之前(顯示ModalViewController view 之前),需要設定委託的執行個體。
- (void)applicationDidFinishLaunching:(UIApplication *)application {
controller = [[CustomViewController alloc] init];
[window addSubview:controller.view];
[window makeKeyAndVisible];
// 建立ModalViewController view 的Controller
CustomViewController* controllerB = [[CustomViewController alloc] init];
// 設定背景色為紅色
controllerB.view.backgroundColor = [UIColor redColor];
// 設定委託執行個體
[controllerB setColorSelectDelegate:controller];
// 顯示ModalViewController view
[controller presentModalViewController:controllerB animated:YES];
[controllerB release];
}
編譯一下,程式啟動後顯示紅色背景的ModalViewController view,點擊綠色按鈕後,原先的view的背景變為綠色,點擊灰色,顯示灰色的背景,而點擊取消,那麼將顯示原先藍色的背景。
這樣的形式,就是將按鈕的動作委託給原先view的Controller 來處理了。根據送來的UIColor 來設定不同的背景色。
摘自:易飛揚