在UIKit中,每个控制器管理着App中的一个页面,多页面的管理方式包括以下几种:

1)使用模态方式切换页面

2)使用导航控制器管理多个页面

3)使用标签控制器管理多个页面


modal,即模态方式,目的控制器被覆盖着源控制器,并接受用户的交互

默认的动作是:从屏幕的下方弹出


下面介绍modal切换方式实现的三种方式以及页面之间数据的传递

代理切换

storyboard的自动型segue

storyboard的自动型segue


代码实现控制器的modal切换

切换动作中涉及的两个控制器

源控制器:执行切换动作的控制器

目的控制器:被切换并显示的控制器


源控制器使用以下方法切换目的控制器:

-(void)presentViewController:(UIViewController*)viewControllerToPresentanimated:(BOOL)flagcompletion:(void(^)(void))completion

viewControllerToPresent参数:目的控制器

flag参数:动画使能

completion参数:切换动作完成时执行的代码

注意:该方法调用时,源控制器必须已经显示,不要在viewDidLoad方法中调用


源控制器和目的控制器使用以下方法完成页面返回的功能:

-(void)dismissViewControllerAnimated:(BOOL)flagcompletion:(void(^)(void))completion

如果是目的控制器调用,会自动交给源控制器去执行返回动作,即源控制器和目的控制器都可以执行,且效果一样。


代码切换:示例1

切换到UIAlertViewController

UIAlertController*ac=[UIAlertControlleralertControllerWithTitle:@"版本更新?"message:@"检测到新版本,是否到AppStore更新?"preferredStyle:UIAlertControllerStyleAlert];UIAlertAction*a1=[UIAlertActionactionWithTitle:@"更新"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction*_Nonnullaction){[[UIApplicationsharedApplication]openURL:updateURL];}];UIAlertAction*a2=[UIAlertActionactionWithTitle:@"算了"style:UIAlertActionStyleCancelhandler:^(UIAlertAction*_Nonnullaction){}];[acaddAction:a1];[acaddAction:a2];[selfpresentViewController:acanimated:YEScompletion:^{NSLog(@"modal");}];

UIAlertController是UIKit中的控制器,并必须使用modal方式显示

UIAlertController内部已经实现了点击按钮执行dismissViewController...方法

UIAlertController用于代替UIAlertView及UIActionSheet


代码切换:示例2

切换到自定义的控制器

//源控制器:执行器执行切换动作AMViewContoller*vc=[[UIViewControlleralloc]init];[selfpresentViewController:vcanimated:YEScompletion:^{NSLog(@"modal");}];

//目的控制器:执行返回动作[selfdismissViewControllerAnimated:YEScompletion:^{NSLog(@"返回");}];


代码切换:控制器间值的传递

正向传递:源控制器将数据传递到目的控制器

传递时机:目的控制器被创建后,目的控制器显示前

传递方法:

目的控制器添加属性

切换前,为目的控制器的属性赋值

//目的控制器@interfaceAMViewControllerTwo:UIViewController@property(nonatomic,copy)NSString*str;@end@implementationAMViewControllerTwo-(void)viewDidLoad{[superviewDidLoad];NSLog(@"源控制器:%@",self.str);}@end

//源控制器的切换动作AMViewControllerTwo*vc=[[AMViewControllerTwoalloc]init];vc.str=@"这是源控制器AMViewControllerOne给你的数据";[selfpresentViewController:vcanimated:YEScompletion:^{NSLog(@"modal");}];


逆向传递:目的控制器将数据传递到源控制器

传递时机:目的控制器返回前

传递方法:

目的控制器添加代理属性并提出代理协议

源控制器成为目的控制器的代理并实现代理方法

dismiss前,调用代理的代理方法并间数据作为方法的参数传递

//目的控制器@classAMViewControllerTwo;@protocolAMViewControllerTwoDelegate:NSObject-(void)viewControllerTwo:(AMViewControllerTwo*)vcdismissWithStr:(NSString*)str;@end@interfaceAMViewControllerTwo@property(nonatomic,copy)NSString*str;@property(nonatomic,weak)id<AMViewControllerTwoDelegate>delegate;@end

//目的控制器执行dimiss动作if(self.delegate&&[self.delegaterespondsToSelector:@selector(viewControllerTwo:dismissWithStr:)]){[self.delegateviewControllerTwo:selfdismissWithStr:@"这是目的控制器AMViewControllerOnew还你的数据"];}[selfdismissViewControllerAnimated:YEScompletion:^{NSLog(@"返回");}];

//源控制器遵循代理协议@interfaceAMViewControllerOne:UIViewController<AMViewControllerTwoDelegate>@end

//源控制器实现代理方法-(void)viewControllerTwo:(AMViewControllerTwo*)vcdismissWithStr:(NSString*)str{NSLog(@"目的控制器:%@",);}

//源控制器的切换动作AMViewControllerTwo*vc=[[AMViewControllerTwoalloc]init];vc.str=@"这是源控制器AMViewControllerOne给你的数据";vc.delegate=self;[selfpresentViewController:vcanimated:YEScompletion:^{NSLog(@"modal");}];