iOS8的UIPresentationController
本文转载至 http://kyfxbl.iteye.com/blog/2147888
从iOS8开始,controller之间的跳转特效,需要用新的API UIPresentationController来实现。比如希望实现这样一个特效:显示一个模态窗口,大小和位置是自定义的,遮罩在原来的页面上。在iOS8之前,可以在viewWillAppear里设置superview的frame:
- - (void)presentModal:(NSDictionary*)result
- {
- YLSCheckoutSignatureController *controller = [[YLSCheckoutSignatureController alloc] initWithModel:result];
- if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
- controller.modalPresentationStyle = UIModalPresentationCustom;
- }else{
- controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
- controller.modalPresentationStyle = UIModalPresentationFormSheet;
- }
- [self presentViewController:controller animated:YES completion:nil];
- }
- -(void) viewWillAppear:(BOOL)animated
- {
- // in iOS8, handle by UIPresentationController
- if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
- return;
- }
- self.view.superview.layer.cornerRadius = 10;
- self.view.superview.layer.borderColor = [UIColor darkGrayColor].CGColor;
- self.view.superview.clipsToBounds = YES;
- self.view.superview.frame = CGRectMake(62, 114, 900, 540);
- }
但是以上的代码,在iOS8里就不再生效了,要用UIPresentationController来实现
首先明确一点,从Controller A->B,B的样式和跳转特效,还是由B来控制的。只不过以前是直接在Controller的生命周期方法里操作,而现在有专门的API来完成而已。这种设计也是合理的,否则如果从A可以跳转到B和C,但是样式和特效不一样,就只能通过在A里面设置实例变量来区分了,容易出错也很别扭。所以把跳转的行为由目标Controller来控制是很合理的
不过这组API的文档不太全,后续SDK升级可能会逐渐完善。以下介绍实现步骤:
目标Controller实现特定protocol
首先目标Controller要实现特定的协议,创建一个UIPresentationController
- @interface YLSCheckoutSignatureController : UIViewController<UIScrollViewDelegate, UIViewControllerTransitioningDelegate>
- self.transitioningDelegate = self;
- - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source
- {
- return [[YLSMainPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
- }
当条件满足时,iOS系统会调用这个方法,于是可以实例化自定义的UIPresentationController子类,定义跳转的样式和特效
自定义UIPresentationController
然后就要实现自定义的UIPresentationController,下面这段实例代码,实现居中展示一个自定义frame的模态页面,同时有半透明背景遮住原来的页面
- @implementation YLSMainPresentationController
- {
- UIView *dimmingView;
- }
- -(id) initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController
- {
- self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController];
- if(self){
- dimmingView = [[UIView alloc] init];
- dimmingView.backgroundColor = [UIColor grayColor];
- dimmingView.alpha = 0.0;
- }
- return self;
- }
- - (void)presentationTransitionWillBegin
- {
- dimmingView.frame = self.containerView.bounds;
- [self.containerView addSubview:dimmingView];
- [self.containerView addSubview:self.presentedView];
- id<UIViewControllerTransitionCoordinator> coordinator = self.presentingViewController.transitionCoordinator;
- [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
- dimmingView.alpha = 0.5;
- } completion:nil];
- }
- - (void)presentationTransitionDidEnd:(BOOL)completed
- {
- if(!completed){
- [dimmingView removeFromSuperview];
- }
- }
- - (void)dismissalTransitionWillBegin
- {
- id<UIViewControllerTransitionCoordinator> coordinator = self.presentingViewController.transitionCoordinator;
- [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
- dimmingView.alpha = 0.0;
- } completion:nil];
- }
- - (void)dismissalTransitionDidEnd:(BOOL)completed
- {
- if(completed){
- [dimmingView removeFromSuperview];
- }
- }
- - (CGRect)frameOfPresentedViewInContainerView
- {
- return CGRectMake(62.f, 114.f, 900.f, 540.f);
- }
- @end
代码确实比以前复杂了一点,但是其实每个生命周期方法都是比较明确的,开发者可控的粒度也更细了。比如设置presented frame,就有专门的方法,只要返回CGRect就可以了,还是比较方便的
原始的ViewController发起跳转动作
经过前面2步,当自定义跳转发生时,就可以很细致地控制样式和跳转行为。接下来就是由原始controller(presenting view controller)来发起跳转动作:
- - (void)presentModal:(NSDictionary*)result
- {
- YLSCheckoutSignatureController *controller = [[YLSCheckoutSignatureController alloc] initWithModel:result];
- if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
- controller.modalPresentationStyle = UIModalPresentationCustom;
- }else{
- controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
- controller.modalPresentationStyle = UIModalPresentationFormSheet;
- }
- [self presentViewController:controller animated:YES completion:nil];
- }
关键是设置modalPresentationStyle为UIModalPresentationCustom,然后当presentViewController方法调用时,iOS系统就会创建出UIPresentationController的实例,来控制跳转的行为
iOS8的UIPresentationController的更多相关文章
- iOS8新特性(2)——UIPopoverController和UIPresentationController
一.以往使用 UIPopoverController 都是只在iPad上使用 /** * UIPopoverController 只能用于iPad,上,iPhone上使用会崩溃 */ -(void)o ...
- iOS iOS8新特性--UIPopoverPresentationController
1.回顾UIPopoverController的使用,下面这份代码只能在ipad下运行 // 初始化控制器,SecondViewController类继承自UIViewController Secon ...
- IOS开发之IOS8.0最新UIAlertController
最近苹果更新的IOS8 对以前进行了很大的修改, 更新的API也让人捉急,据说iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.比如全新的UIPrese ...
- IOS开发之IOS8.0最新UIAlertController 分类: ios技术 2015-01-20 14:24 144人阅读 评论(1) 收藏
最近苹果更新的IOS8 对以前进行了很大的修改, 更新的API也让人捉急,据说iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.比如全新的UIPrese ...
- 【Swift】UIPresentationController的使用方法
UIPresentationController是ios8.0的新特性哦,使用需要注意 先上一个效果图 第一步: 连线选择segue类型为,present Modally 第二步:需要演示的控制器,自 ...
- iOS:自定义模态动画 --UIPresentationController
UIPresentationController :展示控制器,是iOS8的一个新特性,用来展示模态窗口的.它是所有模态控制器的管理者. 即: 1> 管理所有Modal出来的控制器 2> ...
- iOS8需要兼容的内容
本文转载至 http://blog.csdn.net/liuwuguigui/article/details/39494435 1.iPad上使用presentModalViewController ...
- iOS8沙盒路径的变化
iOS8中的的沙盒路径发生了变化 之前是这样的路径,通过NSHomedictionary()获取的家路径 /Users/wupeng/Library/Application Support/iPhon ...
- iOS8中定位服务的变化(CLLocationManager协议方法不响应,无法回掉GPS方法,不出现获取权限提示)
最近在写一个LBS的项目的时候,因为考虑到适配iOS8,就将项目迁移到Xcode6.0.1上,出现了不能正常获取定位服务权限的问题. self.manger = [[CLLocationManager ...
随机推荐
- bzoj 2330 [SCOI2011]糖果 差分约束模板
题目大意 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配 ...
- APUE 学习笔记(一) Unix基础知识
1. Unix 体系结构 内核的接口被称为系统调用 公用函数库构建在系统调用接口之上 应用软件既可以调用公用函数库,也可以直接进行系统调用 2. 文件和目录 目录操作函数:opendir--- ...
- GridView从行寻找到该控件,以及从该控件获知该行
原文发布时间为:2008-08-01 -- 来源于本人的百度文章 [由搬家工具导入] GridView从行寻找到该控件: protected void Button3_Click(object sen ...
- 转载 关于malloc
1.函数原型及说明: void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针.如果分配失败,则返回一个空指针(NULL). 关于分配失败 ...
- buffer和cache怎么让你们解释的那么难理解?
对于一个即将踏上“系统运维”或者更加高大尚的工作“系统调优”,如果这不跟这两哥们搞好关系了,坑的不只有内存,更坑的是你拿着调优的钱却干着随时被调的活.因为作为一个系统运维人员来说监控和优化IO性能这是 ...
- Oracle For 循环添加数据
自己亲自使用的,绝对OK --添加数据declare i number; --用for实现 begin for i in 0 .. 500 loop insert into cust(custsn,t ...
- LaTeX 如何在文档的侧面插入图片实现"绕排"?
https://www.zhihu.com/question/26837705 https://blog.csdn.net/u012856866/article/details/70305834
- 2012 ACM/ICPC 亚洲区 金华站
题目链接 2012金华区域赛 Problem A 按a/b从小到大的顺序排队进行体检即可 #include<iostream> #include<cstdio> #inclu ...
- socket的accept: Invalid argument问题
void local_sdk_server::wait_remote_client_connect_and_comm() { /*服务器服务启动,等待客户端的链接的到来*/ //sockaddr_in ...
- 利用adb截屏
一 第一种方式 二 第二种方式