当程序中含有多个 view,需要在之间切换的时候,可以使用 UINavigationController,或者是 ModalViewController。UINabigationController 是通过向导条来切换多个 view。而如果 view 的数量比较少,且显示领域为全屏的时候,用 ModalViewController 就比较合适(比如需要用户输入信息的view,结束后自动回复到之前的view)。今天我们就看看 ModalViewController 的创建方法。
ModalViewController 并不像 UINavigationController 是一个专门的类,使用 UIViewController 的 presentModalViewController 方法指定之后就是 ModalViewController 了。
这里使用上两回做成的 CustomViewController(由UIViewController继承)来实现 ModalViewController 的实例。
首先,准备 ModalViewController 退出时的函数。调用 UIViewController 的 dismissModalViewController:Animated: 方法就可以了,如下所示:
接下来,生成另一个 CustomViewController 的实例,用来表示 ModalViewController,并将其对应的 view 设置成红色。然后传递给 presentModalViewController: Animated: 显示 ModalViewController 的 view。
编译执行以后,首先启动的是红色背景的 ModalViewController view、按下按钮后恢复到蓝色背景的通常 view 上。
也可以在显示 ModalViewController view 之前设置 UIViewContrller 的 modalTransitionStyle 属性,使其以动画形式显示。
以上的实现只是单一地实现了 ModalViewController view 的功能,除了程序开始提醒用户一些信息外什么也做不了。另外由于是放入了 applicationDidFinishLaunching 中的原因,也不能反复的显示。另外,在 ModalViewController view 上设置的内容也不能反映到原来的 view 上。
接下来我们将实现这些功能。
首先,从 ModalViewController view 退出的时候,需要通知原先的 view。这里使用 iPhone/Cocoa 应用程序中经常使用的Delegate 设计模式(也是推荐使用的)。
实际上,系统所提供的图像选择控制类 UIImagePickerController
或者是参照地址簿时的ABPeoplePickerNavigationController 类,都用到了 Delegate 模式。
基于上一讲的中的例子,这里我们追加为3个按钮,分别是绿色,灰色和取消。
程序启动的时候依然是先显示 ModalViewController view,按下任何一个按钮,将关闭该view。按下“绿色”按钮,设置背景为绿色,按下“灰色”按钮时,设置背景为灰色。“取消”的时候什么也不做。
委托处理用下面的函数实现,当参数 inColor 为 nil 的时候代表取消。
委托代理的实例用 id 变量表示。
设置该变量的函数如下。
另外如上面 viewDidLoad 所示,按钮的 tag 分别为0、1、2。按钮按下时调用的函数中由不同的 tag 来发送不同的 UIColor实例到 colorSelectDelegate 上。
这是不使用 UIButton* 而是用 UIView* ,是因为 tag 属性被定义在 UIView 类中,不需要必须转换为 UIButton 类。
另外这样一来,该函数在 UIButton 以外的情况下也能被使用。
如果想检查 id 是什么类性的可以使用 isKindOfClass: 方法。
接收到具体的参数 inColor 更换背景色,并关闭 ModalViewController view。
另外,在调用 presentModalViewController 之前(显示 ModalViewController view 之前),需要设定委托的实例。
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
];
}
|
01
02
03
04
05
06
07
08
09
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 之前设置 UIViewContrller 的 modalTransitionStyle 属性,使其以动画形式显示。
1
|
controllerB.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
|
接下来我们将实现这些功能。
首先,从 ModalViewController view 退出的时候,需要通知原先的 view。这里使用 iPhone/Cocoa 应用程序中经常使用的Delegate 设计模式(也是推荐使用的)。
实际上,系统所提供的图像选择控制类 UIImagePickerController
或者是参照地址簿时的ABPeoplePickerNavigationController 类,都用到了 Delegate 模式。
基于上一讲的中的例子,这里我们追加为3个按钮,分别是绿色,灰色和取消。
01
02
03
04
05
06
07
08
09
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];
}
|
委托处理用下面的函数实现,当参数 inColor 为 nil 的时候代表取消。
1
|
-(
void
)selectColor:(UIColor*)inColor;
|
1
2
3
|
@interface
CustomViewController : UIViewController {
id
colorSelectDelegate;
}
|
1
2
3
|
-(
void
)setColorSelectDelegate:(
id
)inDelegate {
colorSelectDelegate = inDelegate;
}
|
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 以外的情况下也能被使用。
如果想检查 id 是什么类性的可以使用 isKindOfClass: 方法。
接收到具体的参数 inColor 更换背景色,并关闭 ModalViewController view。
1
2
3
4
5
|
-(
void
)selectColor:(UIColor*)inColor {
if
(inColor !=
nil
)
self
.view.backgroundColor = inColor;
[
self
dismissModalViewControllerAnimated:
YES
];
}
|
01
02
03
04
05
06
07
08
09
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 来设置不同的背景色。