在一个正常的IOS应用中,必然包括很多视图,我们需要在不同的视图中进行跳转,常见的方法有模态视图、UItabarController、UINavigationController进行视图之间的跳转,本篇博客总结模态视图的常见的用法
一、目录
1.什么是模态视图
2.模态视图的主要用途
3.简单的使用
4.常见的属性
5.视图间交互处理
二、什么是模态视图
IOS的应用中使用了大量的模态视图。如IOS自带的日历和Passbook应用,点击日历“+”号时弹出New Event,点击Cancel消失。
三、模态视图的主要用途
1.收集用户的输入信息
2.临时呈现一些内容
3.临时改变工作模式
4.相应设备方向变化(用于针对不同方向分布式两个ViewController的情况)
5.显示一个新的View层级
这几种情形都会暂时中断程序正常的执行流程,主要的作用是收集或者显示一些信息
四、简单使用
简单的用模态视图实现如下简单的效果,点击第一个控制器的按钮跳转到第二个页面,然后点击第二个页面按钮,再返回第一个页面
程序的代码结构如下:
1.在AppDelegate中将FistViewCtrl设置为根控制器
// // AppDelegate.m // TestJump // // Created by gurk on 15/3/13. // Copyright (c) 2015年 thinkive. All rights reserved. // #import "AppDelegate.h" #import "FirstViewCtrl.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; FirstViewCtrl *firstViewCtrl = [[FirstViewCtrl alloc]init]; //设置根视图为第一个 self.window.rootViewController = firstViewCtrl; [self.window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { } - (void)applicationDidEnterBackground:(UIApplication *)application { } - (void)applicationWillEnterForeground:(UIApplication *)application { } - (void)applicationDidBecomeActive:(UIApplication *)application { } - (void)applicationWillTerminate:(UIApplication *)application { } @end
2.在FistViewCtrl中调用
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion NS_AVAILABLE_IOS(5_0);方法弹出模态视图
// // FirstViewCtrl.m // TestJump // // Created by gurk on 15/3/13. // Copyright (c) 2015年 thinkive. All rights reserved. // #import "FirstViewCtrl.h" #import "SecondViewCtrl.h" @implementation FirstViewCtrl - (void)viewDidLoad { [super viewDidLoad]; //为区分不同的控制器,设置背景色 [self.view setBackgroundColor:[UIColor whiteColor]]; //跳转按钮 UIButton *jumpToSeconViewBtn = [[UIButton alloc]initWithFrame:CGRectMake(50, 100, 200, 50)]; [jumpToSeconViewBtn addTarget:self action:@selector(jumpToSecondViewCtrFunction) forControlEvents:UIControlEventTouchUpInside]; [jumpToSeconViewBtn setBackgroundColor:[UIColor redColor]]; [jumpToSeconViewBtn setTitle:@"跳转到第二个控制器" forState:UIControlStateNormal]; [self.view addSubview:jumpToSeconViewBtn]; } //跳转第二个控制器的方法 -(void)jumpToSecondViewCtrFunction { SecondViewCtrl *secondViewCtrl = [[SecondViewCtrl alloc]init]; //在此处调用方法,弹出模态视图 [self presentViewController:secondViewCtrl animated:YES completion:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
3.进入SeconViewCtrl之后,让模态视图消失,可以调用
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion NS_AVAILABLE_IOS(5_0);
// // SecondViewCtrl.m // TestJump // // Created by gurk on 15/3/13. // Copyright (c) 2015年 thinkive. All rights reserved. // #import "SecondViewCtrl.h" @implementation SecondViewCtrl - (void)viewDidLoad { [super viewDidLoad]; //设置背景色区分不同的视图控制器 [self.view setBackgroundColor:[UIColor yellowColor]]; UIButton *backFistViewCtrlBtn = [[UIButton alloc]initWithFrame:CGRectMake(50, 100, 200, 50)]; [backFistViewCtrlBtn addTarget:self action:@selector(backFisrtViewCtrlFunction) forControlEvents:UIControlEventTouchUpInside]; [backFistViewCtrlBtn setBackgroundColor:[UIColor redColor]]; [backFistViewCtrlBtn setTitle:@"返回第一个页面" forState:UIControlStateNormal]; [self.view addSubview:backFistViewCtrlBtn]; } -(void)backFisrtViewCtrlFunction { //让模态视图消失 [self dismissViewControllerAnimated:YES completion:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
五、常见的属性
在弹出模态窗口的时候,我们可以设置被弹出窗口的不同的属性,使得弹出窗口呈现不同的外观样式和动画效果。
1.presenting view controller Vs presented view controller
当我们在view controller A中模态显示view controller B的时候,A就充当presenting view controller(弹出VC),而B就是presented view controller(被弹出VC)。
2.Modal Presentation Stytkes(弹出的类型)
本属性只在ipad上面有效,在iPhone和iPod上面系统始终已UIModalPresentationFullScreen模式显示被弹出的视图控制器。
通过设置被弹出模态视图控制器的modalPresentationStytle的属性,我们可以设置弹出视图的风格,常见的有以下几种
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) { UIModalPresentationFullScreen = 0, UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2), UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2), UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2), UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0), UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0), UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0), UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0), UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1, };
接上面代码在FistViewCtrl中新加代码,测试以上属性
// // FirstViewCtrl.m // TestJump // // Created by gurk on 15/3/13. // Copyright (c) 2015年 thinkive. All rights reserved. // #import "FirstViewCtrl.h" #import "SecondViewCtrl.h" @implementation FirstViewCtrl - (void)viewDidLoad { [super viewDidLoad]; //为区分不同的控制器,设置背景色 [self.view setBackgroundColor:[UIColor whiteColor]]; //跳转按钮 UIButton *jumpToSeconViewBtn = [[UIButton alloc]initWithFrame:CGRectMake(50, 100, 200, 50)]; [jumpToSeconViewBtn addTarget:self action:@selector(jumpToSecondViewCtrFunction) forControlEvents:UIControlEventTouchUpInside]; [jumpToSeconViewBtn setBackgroundColor:[UIColor redColor]]; [jumpToSeconViewBtn setTitle:@"跳转到第二个控制器" forState:UIControlStateNormal]; [self.view addSubview:jumpToSeconViewBtn]; } //跳转第二个控制器的方法 -(void)jumpToSecondViewCtrFunction { //测试modalPresentationStyle属性 SecondViewCtrl *secondViewCtrl = [[SecondViewCtrl alloc]init]; //secondViewCtrl.modalPresentationStyle = secondViewCtrl.modalPresentationStyle = UIModalPresentationFullScreen; //secondViewCtrl.modalPresentationStyle = UIModalPresentationPageSheet; //secondViewCtrl.modalPresentationStyle = UIModalPresentationFormSheet; secondViewCtrl.modalPresentationStyle = UIModalPresentationCurrentContext; //在此处调用方法,弹出模态视图 [self presentViewController:secondViewCtrl animated:YES completion:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
UIModalPresentationFullScreen代表弹出视图控制器时,被弹出视图控制器充满全屏,如果弹出视图控制器的wantsFullScreenLayout设置为YES的,则会填充到状态栏下边,否则不会填充到状态栏之下。
UIModalPresentationPageSheet代表弹出是弹出VC时,presented VC的高度和当前屏幕高度相同,宽度和竖屏模式下屏幕宽度相同,剩余未覆盖区域将会变暗并阻止用户点击,这种弹出模式下,竖屏时跟UIModalPresentationFullScreen的效果一样,横屏时候两边则会留下变暗的区域。
UIModalPresentationFormSheet这种模式下,presented VC的高度和宽度均会小于屏幕尺寸,presented VC居中显示,四周留下变暗区域。
UIModalPresentationCurrentContext这种模式下,presented VC的弹出方式和presenting VC的父VC的方式相同。
3.Modal Transition Style(弹出时的动画风格)
通过设置设置presenting VC的modalTransitionStyle属性,我们可以设置弹出presented VC时场景切换动画的风格,其定义如下:
typedef NS_ENUM(NSInteger, UIModalTransitionStyle) { UIModalTransitionStyleCoverVertical = 0, UIModalTransitionStyleFlipHorizontal, UIModalTransitionStyleCrossDissolve, UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2), };
接上面代码仔FistViewCtrl中新加代码,测试以上属性
// // FirstViewCtrl.m // TestJump // // Created by gurk on 15/3/13. // Copyright (c) 2015年 thinkive. All rights reserved. // #import "FirstViewCtrl.h" #import "SecondViewCtrl.h" @implementation FirstViewCtrl - (void)viewDidLoad { [super viewDidLoad]; //为区分不同的控制器,设置背景色 [self.view setBackgroundColor:[UIColor whiteColor]]; //跳转按钮 UIButton *jumpToSeconViewBtn = [[UIButton alloc]initWithFrame:CGRectMake(50, 100, 200, 50)]; [jumpToSeconViewBtn addTarget:self action:@selector(jumpToSecondViewCtrFunction) forControlEvents:UIControlEventTouchUpInside]; [jumpToSeconViewBtn setBackgroundColor:[UIColor redColor]]; [jumpToSeconViewBtn setTitle:@"跳转到第二个控制器" forState:UIControlStateNormal]; [self.view addSubview:jumpToSeconViewBtn]; } //跳转第二个控制器的方法 -(void)jumpToSecondViewCtrFunction { //测试modalTransitionStyle属性 SecondViewCtrl *secondViewCtrl = [[SecondViewCtrl alloc]init]; //secondViewCtrl.modalTransitionStyle = UIModalTransitionStyleCoverVertical; //secondViewCtrl.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; // secondViewCtrl.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; secondViewCtrl.modalTransitionStyle = UIModalTransitionStylePartialCurl; [self presentViewController:secondViewCtrl animated:YES completion:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
UIModalTransitionStyleCoverVertical 底部滑入 UIModalTransitionStyleFlipHorizontal水平翻转进入
UIModalTransitionStyleCrossDissolve交叉溶解 UIModalTransitionStylePartialCurl 翻页
六、视图间交互处理
在视图跳转之间需要传递一些数据,在IOS开发中常见的传递参数的方法有以下几种,
1.通过控制器的属性传递
2.通过在AppDelegate定义全局变量
3.通过NSDefault存储(或者文件,数据库等)
4.使用IOS的NSNotificationCenter传递
5.使用代理模式
现在实现如下效果,在FistViewCtrl中点击按钮,传递参数到SecondViewCtrl,在SecondViewCtrl的UILable中显示由第一个控制器传递过来的参数,效果如下图
第一种方法使用控制器的属性,修改FistViewCtrl.m文件如下,添加要传递的参数info,并在修改SecondViewCtrl的showInfoLable中展示传递过来的参数
// // FirstViewCtrl.m // TestJump // // Created by gurk on 15/3/13. // Copyright (c) 2015年 thinkive. All rights reserved. // #import "FirstViewCtrl.h" #import "SecondViewCtrl.h" @implementation FirstViewCtrl - (void)viewDidLoad { [super viewDidLoad]; //为区分不同的控制器,设置背景色 [self.view setBackgroundColor:[UIColor whiteColor]]; //跳转按钮 UIButton *jumpToSeconViewBtn = [[UIButton alloc]initWithFrame:CGRectMake(50, 100, 200, 50)]; [jumpToSeconViewBtn addTarget:self action:@selector(jumpToSecondViewCtrFunction) forControlEvents:UIControlEventTouchUpInside]; [jumpToSeconViewBtn setBackgroundColor:[UIColor redColor]]; [jumpToSeconViewBtn setTitle:@"跳转到第二个控制器" forState:UIControlStateNormal]; [self.view addSubview:jumpToSeconViewBtn]; } //跳转第二个控制器的方法 -(void)jumpToSecondViewCtrFunction { //将info传递给SecondViewCtrl NSString *info = @"来自FirstViewCtrl"; SecondViewCtrl *secondViewCtrl = [[SecondViewCtrl alloc]init]; secondViewCtrl.getInfo = info; //采用控制器的属性传递 [self presentViewController:secondViewCtrl animated:YES completion:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
SecondViewCtr.h的代码
// // SecondViewCtrl.h // TestJump // // Created by gurk on 15/3/13. // Copyright (c) 2015年 thinkive. All rights reserved. // #import <UIKit/UIKit.h> @interface SecondViewCtrl : UIViewController //添加此属性用来传递参数 @property(nonatomic,copy)NSString *getInfo; @end
SecondViewCtr.m的代码
// // SecondViewCtrl.m // TestJump // // Created by gurk on 15/3/13. // Copyright (c) 2015年 thinkive. All rights reserved. // #import "SecondViewCtrl.h" @implementation SecondViewCtrl @synthesize getInfo; - (void)viewDidLoad { [super viewDidLoad]; //设置背景色区分不同的视图控制器 [self.view setBackgroundColor:[UIColor yellowColor]]; UIButton *backFistViewCtrlBtn = [[UIButton alloc]initWithFrame:CGRectMake(50, 100, 200, 50)]; [backFistViewCtrlBtn addTarget:self action:@selector(backFisrtViewCtrlFunction) forControlEvents:UIControlEventTouchUpInside]; [backFistViewCtrlBtn setBackgroundColor:[UIColor redColor]]; [backFistViewCtrlBtn setTitle:@"返回第一个页面" forState:UIControlStateNormal]; [self.view addSubview:backFistViewCtrlBtn]; //定义一个UIlable接受传递过来的数据 UILabel *showInfoLable = [[UILabel alloc]initWithFrame:CGRectMake(50, 160, 200, 50)]; [showInfoLable setTextColor:[UIColor whiteColor]]; [showInfoLable setBackgroundColor:[UIColor redColor]]; //展示获取的参数 [showInfoLable setText:self.getInfo]; [self.view addSubview:showInfoLable]; } -(void)backFisrtViewCtrlFunction { //让模态视图消失 [self dismissViewControllerAnimated:YES completion:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
第二种方法,使用代理模式传递参数
在官方的文档中建议使用delegate实现交互,在被弹出的VC中定义delegate,然后在弹出VC中实现该代理,这样方便的实现两者的交互。用此方法实现传递参数
----------------------未完待续------------------------