模态窗口
一. 简介1. 简介由于在iOS中并没有专门的模态窗口类,模态窗口(modal)在iOS中只是视图控制器显示的一种方式,模态窗口方便快捷,它不依赖于控制器容器(如UITabBarController和UINavigationController),通常用于显示独立的内容,在模态窗口显示的时候,它暂时中断程序正常的执行流程,用户无法再与上一个场景交互,只能对当前此窗口进行操作,除非他们先
一. 简介
在iOS中并没有专门的模态窗口类,模态窗口(modal)只是视图控制器显示的一种方式,模态窗口方便快捷,它不依赖于控制器容器(如UITabBarController和UINavigationController),通常用于显示独立的内容,在模态窗口显示的时候,它暂时中断程序正常的执行流程,用户无法再与上一个场景交互,只能对当前此窗口进行操作,除非他们先关闭这个场景,而普通窗口则可以进行任意切换
推荐一篇可以加深对模态理解的博文: http://blog.csdn.net/ssirreplaceable/article/details/52335465
1. 使用场景
模态视图(modal)最常用的场景是临时弹出的窗口,如登陆注册、设置、购物车、点赞等展示小功能的窗口
使用场景可分为下面几类:
a. 收集用户输入信息
b. 临时呈现一些内容
c. 临时改变工作模式
d. 为不同的设备方向实现可替代的界面
e. 使用指定类型的过渡动画来显示一个新的视图结构
2. 基本概念
模态:一种用来承载特定内容、功能或体验的模式,有其自身的优缺点。它可以帮助用户完成某些任务,或在不受干扰的情况下获取信息,但会暂时性的强迫用户停止与应用其他部分的互动
模态视图:也称为模态窗口,由于在iOS中并没有专门的模态窗口类,模态窗口(modal)在iOS中只是视图控制器显示的一种方式,通过presentViewController方法弹出的视图我们都称为模态视图
二. 知识点
模态视图没有父控制器,即当视图通过parentViewController获取父视图时,返回nil
当我们在viewController A中模态显示viewController B的时候,A就充当presentingViewController(弹出模态窗口的控制器),而B就是presentedViewController(被弹出控制器)
当连续获取presentingViewController,可以得到根视图控制器
// 当连续两次展现模态视图时,可以通过下面代码获取根视图控制器,self指向最后展现的模态窗口
UIViewController *vc = self.presentingViewController.presentingViewController;
三. 展现和关闭模态视图方法
present方法和dismiss方法一般一起使用,才能实现两个视图之间的来回切换
completion是一个block类型的处理器,用于在调用present方法或dismiss方法之后执行回调
// 展示模态视图
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion NS_AVAILABLE_IOS(5_0);
// 关闭模态视图
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion NS_AVAILABLE_IOS(5_0);
四. 模态窗口的切换风格
必须在presenting控制器里设置
(1). Modal Presentation Styles(弹出风格)
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,
};
(2). Modal Transition Style(弹出时的动画风格)
typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2),
};
五. 窗口之间的传值
- 接收方必须要有一个接收数据的属性
- 可以通过presentingViewController获取弹出模态视图的那个控制器,而通过presentedViewController可获取被弹出的控制器视图
- 从前往后传值,要先调用presentViewController:animated:completion:方法才能进行传值,不能在调用之前传值,否者无法传值
- 从后往前传值,要先传值再调用dismissViewControllerAnimated:completion:方法,不能在调用之后传值,否者无法传值
- 官方文档建议这两者之间通过delegate实现交互
补充:之后会补充关于界面传值的文章
四. 具体使用
(一). storyboard中的使用
在storyboard里使用模态视图,即切换模式为modal,只能通过代码返回
1. 在视图控制器1选中“按钮”按住Ctrl键,拖线到视图控制器2,并选中modal切换模式
2. 设置视图控制器2的所属类
3. 编写返回按钮的响应方法,即通过代码关闭模态视图
#import "TwoViewController.h"
@interface TwoViewController ()
@end
@implementation TwoViewController
- (IBAction)gotoOne:(id)sender {
[self dismissViewControllerAnimated: YES completion:nil];
}
@end
(二). 纯代码实现
1. ViewController类
---------- ViewController.h文件
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (nonatomic,strong) NSString *oneData;
@end
---------- ViewController.m文件
#import "ViewController.h"
#import "TwoViewController.h"
@interface ViewController ()
@property (nonatomic,strong) UIButton *gotoTwoBtn;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 设置背景颜色
self.view.backgroundColor = [UIColor blueColor];
// 创建模态切换按钮
_gotoTwoBtn = [[UIButton alloc] init];
_gotoTwoBtn.frame = CGRectMake(100, 150, 80, 60);
[_gotoTwoBtn setBackgroundImage:[UIImage imageNamed:@"beijing"] forState:UIControlStateNormal];
[_gotoTwoBtn addTarget:self action:@selector(gotoTwo) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_gotoTwoBtn];
}
- (void)gotoTwo{
TwoViewController *twoVC = [[TwoViewController alloc] init];
[self presentViewController:twoVC animated:YES completion:nil];
// 要先执行presentViewController:animated:completion:才能执行下面语句
[self.presentedViewController setValue:@"界面1到界面2" forKey:@"twoData"];
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(@"%@ -- %@",self,_oneData);
}
@end
2. TwoViewController类
---------- TwoViewController.h文件
#import <UIKit/UIKit.h>
@interface TwoViewController : UIViewController
@property (nonatomic,strong) NSString *twoData;
@end
---------- TwoViewController.m文件
#import "TwoViewController.h"
#import "TreeViewController.h"
@interface TwoViewController ()
@property (nonatomic,strong) UIButton *backOneBtn;
@property (nonatomic,strong) UIButton *gotoTreeBtn;
@end
@implementation TwoViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 设置视图背景颜色
self.view.backgroundColor = [UIColor greenColor];
// 创建模态关闭按钮
_backOneBtn = [[UIButton alloc] init];
_backOneBtn.frame = CGRectMake(100, 150, 80, 60);
[_backOneBtn setBackgroundImage:[UIImage imageNamed:@"beijing"] forState:UIControlStateNormal];
[_backOneBtn addTarget:self action:@selector(gotoOne) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_backOneBtn];
// 创建模态切换按钮
_gotoTreeBtn = [[UIButton alloc] init];
_gotoTreeBtn.frame = CGRectMake(100, 250, 80, 60);
[_gotoTreeBtn setBackgroundImage:[UIImage imageNamed:@"beijing"] forState:UIControlStateNormal];
[_gotoTreeBtn addTarget:self action:@selector(gotoTree) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_gotoTreeBtn];
}
- (void)gotoOne{
[self.presentingViewController setValue:@"界面2到界面1" forKey:@"oneData"];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)gotoTree{
TreeViewController *treeVC = [[TreeViewController alloc] init];
[self presentViewController:treeVC animated:YES completion:nil];
[self.presentedViewController setValue:@"界面2到界面3" forKey:@"treeData"];
}
- (void)viewWillAppear:(BOOL)animated {
NSLog(@"%@ -- %@",self,_twoData);
}
@end
3. TreeViewController类
---------- TreeViewController.h文件
#import <UIKit/UIKit.h>
@interface TreeViewController : UIViewController
@property (nonatomic,strong) NSString *treeData;
@end
---------- TreeViewController.m文件
#import "TreeViewController.h"
@interface TreeViewController ()
@property (nonatomic,strong) UIButton *backTwoBtn;
@property (nonatomic,strong) UIButton *backOneBtn;
@end
@implementation TreeViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 设置视图背景颜色
self.view.backgroundColor = [UIColor redColor];
// 创建模态关闭按钮
_backTwoBtn = [[UIButton alloc] init];
_backTwoBtn.frame = CGRectMake(100, 150, 80, 60);
[_backTwoBtn setBackgroundImage:[UIImage imageNamed:@"beijing"] forState:UIControlStateNormal];
[_backTwoBtn addTarget:self action:@selector(gotoTwo) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_backTwoBtn];
// 创建模态切换按钮
_backOneBtn = [[UIButton alloc] init];
_backOneBtn.frame = CGRectMake(100, 250, 80, 60);
[_backOneBtn setBackgroundImage:[UIImage imageNamed:@"beijing"] forState:UIControlStateNormal];
[_backOneBtn addTarget:self action:@selector(gotoOne) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_backOneBtn];
}
- (void)gotoTwo{
[self.presentingViewController setValue:@"界面3到界面2" forKey:@"twoData"];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)gotoOne{
// 连续presentingViewController可以获取根控制器
UIViewController *vc = self.presentingViewController.presentingViewController;
[vc setValue:@"界面3到界面1" forKey:@"oneData"];
[vc dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(@"%@ -- %@",self,_treeData);
}
@end
更多推荐
所有评论(0)