iPhone開發進階(7)--- 利用ModalViewController切換View
當程序中含有多個 view,需要在之間切換的時候,可以使用 UINavigationController,或者是 ModalViewController。UINabigationController 是通過嚮導條來切換多個 view。而如果 view 的數量比較少,且顯示領域爲全屏的時候,用 ModalViewController 就比較合適(比如需要用戶輸入信息的view,結束後自動回覆到之前的view)。今天我們就看看 ModalViewController 的創建方法。
ModalViewController 並不像 UINavigationController 是一個專門的類,使用 UIViewController 的 presentModalViewController 方法指定之後就是 ModalViewController 了。
這裏使用上兩回做成的 CustomViewController(由UIViewController繼承)來實現 ModalViewController 的實例。
首先,準備 ModalViewController 退出時的函數。調用 UIViewController 的 dismissModalViewController:Animated: 方法就可以了,如下所示:
1 2 3 4 5 |
// 這裏按鈕按下的時候退出 ModalViewController -(void)dismiss:(id)inSender { // 如果是被 presentModalViewController 以外的實例調用,parentViewController 將是nil,下面的調用無效 [self.parentViewController dismissModalViewControllerAnimated:YES]; } |
接下來,生成另一個 CustomViewController 的實例,用來表示 ModalViewController,並將其對應的 view 設置成紅色。然後傳遞給 presentModalViewController: Animated: 顯示 ModalViewController 的 view。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
- (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個按鈕,分別是綠色,灰色和取消。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
- (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 的時候代表取消。
1 |
-(void)selectColor:(UIColor*)inColor; |
委託代理的實例用 id 變量表示。
1 2 3 |
@interface CustomViewController : UIViewController { id colorSelectDelegate; } |
設置該變量的函數如下。
1 2 3 |
-(void)setColorSelectDelegate:(id)inDelegate { colorSelectDelegate = inDelegate; } |
另外如上面 viewDidLoad 所示,按鈕的 tag 分別爲0、1、2。按鈕按下時調用的函數中由不同的 tag 來發送不同的 UIColor實例到 colorSelectDelegate 上。
1 2 3 4 5 6 7 8 9 |
-(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。
1 2 3 4 5 |
-(void)selectColor:(UIColor*)inColor { if (inColor != nil) self.view.backgroundColor = inColor; [self dismissModalViewControllerAnimated:YES]; } |
另外,在調用 presentModalViewController 之前(顯示 ModalViewController view 之前),需要設定委託的實例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
- (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 來設置不同的背景色。