本文转载至 http://kyfxbl.iteye.com/blog/2147888

从iOS8开始,controller之间的跳转特效,需要用新的API UIPresentationController来实现。比如希望实现这样一个特效:显示一个模态窗口,大小和位置是自定义的,遮罩在原来的页面上。在iOS8之前,可以在viewWillAppear里设置superview的frame:

  1. - (void)presentModal:(NSDictionary*)result
  2. {
  3. YLSCheckoutSignatureController *controller = [[YLSCheckoutSignatureController alloc] initWithModel:result];
  4. if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
  5. controller.modalPresentationStyle = UIModalPresentationCustom;
  6. }else{
  7. controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
  8. controller.modalPresentationStyle = UIModalPresentationFormSheet;
  9. }
  10. [self presentViewController:controller animated:YES completion:nil];
  11. }
  1. -(void) viewWillAppear:(BOOL)animated
  2. {
  3. // in iOS8, handle by UIPresentationController
  4. if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
  5. return;
  6. }
  7. self.view.superview.layer.cornerRadius = 10;
  8. self.view.superview.layer.borderColor = [UIColor darkGrayColor].CGColor;
  9. self.view.superview.clipsToBounds = YES;
  10. self.view.superview.frame = CGRectMake(62, 114, 900, 540);
  11. }

但是以上的代码,在iOS8里就不再生效了,要用UIPresentationController来实现

首先明确一点,从Controller A->B,B的样式和跳转特效,还是由B来控制的。只不过以前是直接在Controller的生命周期方法里操作,而现在有专门的API来完成而已。这种设计也是合理的,否则如果从A可以跳转到B和C,但是样式和特效不一样,就只能通过在A里面设置实例变量来区分了,容易出错也很别扭。所以把跳转的行为由目标Controller来控制是很合理的

不过这组API的文档不太全,后续SDK升级可能会逐渐完善。以下介绍实现步骤:

目标Controller实现特定protocol

首先目标Controller要实现特定的协议,创建一个UIPresentationController

  1. @interface YLSCheckoutSignatureController  : UIViewController<UIScrollViewDelegate, UIViewControllerTransitioningDelegate>
  1. self.transitioningDelegate = self;
  1. - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source
  2. {
  3. return [[YLSMainPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
  4. }

当条件满足时,iOS系统会调用这个方法,于是可以实例化自定义的UIPresentationController子类,定义跳转的样式和特效

自定义UIPresentationController

然后就要实现自定义的UIPresentationController,下面这段实例代码,实现居中展示一个自定义frame的模态页面,同时有半透明背景遮住原来的页面

  1. @implementation YLSMainPresentationController
  2. {
  3. UIView *dimmingView;
  4. }
  5. -(id) initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController
  6. {
  7. self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController];
  8. if(self){
  9. dimmingView = [[UIView alloc] init];
  10. dimmingView.backgroundColor = [UIColor grayColor];
  11. dimmingView.alpha = 0.0;
  12. }
  13. return self;
  14. }
  15. - (void)presentationTransitionWillBegin
  16. {
  17. dimmingView.frame = self.containerView.bounds;
  18. [self.containerView addSubview:dimmingView];
  19. [self.containerView addSubview:self.presentedView];
  20. id<UIViewControllerTransitionCoordinator> coordinator = self.presentingViewController.transitionCoordinator;
  21. [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
  22. dimmingView.alpha = 0.5;
  23. } completion:nil];
  24. }
  25. - (void)presentationTransitionDidEnd:(BOOL)completed
  26. {
  27. if(!completed){
  28. [dimmingView removeFromSuperview];
  29. }
  30. }
  31. - (void)dismissalTransitionWillBegin
  32. {
  33. id<UIViewControllerTransitionCoordinator> coordinator = self.presentingViewController.transitionCoordinator;
  34. [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
  35. dimmingView.alpha = 0.0;
  36. } completion:nil];
  37. }
  38. - (void)dismissalTransitionDidEnd:(BOOL)completed
  39. {
  40. if(completed){
  41. [dimmingView removeFromSuperview];
  42. }
  43. }
  44. - (CGRect)frameOfPresentedViewInContainerView
  45. {
  46. return CGRectMake(62.f, 114.f, 900.f, 540.f);
  47. }
  48. @end

代码确实比以前复杂了一点,但是其实每个生命周期方法都是比较明确的,开发者可控的粒度也更细了。比如设置presented frame,就有专门的方法,只要返回CGRect就可以了,还是比较方便的

原始的ViewController发起跳转动作

经过前面2步,当自定义跳转发生时,就可以很细致地控制样式和跳转行为。接下来就是由原始controller(presenting view controller)来发起跳转动作:

  1. - (void)presentModal:(NSDictionary*)result
  2. {
  3. YLSCheckoutSignatureController *controller = [[YLSCheckoutSignatureController alloc] initWithModel:result];
  4. if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
  5. controller.modalPresentationStyle = UIModalPresentationCustom;
  6. }else{
  7. controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
  8. controller.modalPresentationStyle = UIModalPresentationFormSheet;
  9. }
  10. [self presentViewController:controller animated:YES completion:nil];
  11. }

关键是设置modalPresentationStyle为UIModalPresentationCustom,然后当presentViewController方法调用时,iOS系统就会创建出UIPresentationController的实例,来控制跳转的行为

iOS8的UIPresentationController的更多相关文章

  1. iOS8新特性(2)——UIPopoverController和UIPresentationController

    一.以往使用 UIPopoverController 都是只在iPad上使用 /** * UIPopoverController 只能用于iPad,上,iPhone上使用会崩溃 */ -(void)o ...

  2. iOS iOS8新特性--UIPopoverPresentationController

    1.回顾UIPopoverController的使用,下面这份代码只能在ipad下运行 // 初始化控制器,SecondViewController类继承自UIViewController Secon ...

  3. IOS开发之IOS8.0最新UIAlertController

    最近苹果更新的IOS8 对以前进行了很大的修改, 更新的API也让人捉急,据说iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.比如全新的UIPrese ...

  4. IOS开发之IOS8.0最新UIAlertController 分类: ios技术 2015-01-20 14:24 144人阅读 评论(1) 收藏

    最近苹果更新的IOS8 对以前进行了很大的修改, 更新的API也让人捉急,据说iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.比如全新的UIPrese ...

  5. 【Swift】UIPresentationController的使用方法

    UIPresentationController是ios8.0的新特性哦,使用需要注意 先上一个效果图 第一步: 连线选择segue类型为,present Modally 第二步:需要演示的控制器,自 ...

  6. iOS:自定义模态动画 --UIPresentationController

    UIPresentationController :展示控制器,是iOS8的一个新特性,用来展示模态窗口的.它是所有模态控制器的管理者. 即: 1> 管理所有Modal出来的控制器 2>  ...

  7. iOS8需要兼容的内容

    本文转载至  http://blog.csdn.net/liuwuguigui/article/details/39494435 1.iPad上使用presentModalViewController ...

  8. iOS8沙盒路径的变化

    iOS8中的的沙盒路径发生了变化 之前是这样的路径,通过NSHomedictionary()获取的家路径 /Users/wupeng/Library/Application Support/iPhon ...

  9. iOS8中定位服务的变化(CLLocationManager协议方法不响应,无法回掉GPS方法,不出现获取权限提示)

    最近在写一个LBS的项目的时候,因为考虑到适配iOS8,就将项目迁移到Xcode6.0.1上,出现了不能正常获取定位服务权限的问题. self.manger = [[CLLocationManager ...

随机推荐

  1. 洛谷P1469找筷子

    题目描述 经过一段时间的紧张筹备,电脑小组的“RP餐厅”终于开业了,这天,经理LXC接到了一个定餐大单,可把大家乐坏了!员工们齐心协力按要求准备好了套餐正准备派送时,突然碰到一个棘手的问题,筷子!CX ...

  2. 【Visual Studio】LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_

    出现这个问题的原因:工程在转换过程中,发现有一些工程使用MD编译选项,有一些工程使用MTD编译选项,导致静态和动态连接MSVC的连接库有冲突.将全部工程改变MT或MTD编译,即可以解决. 工程 —&g ...

  3. 转 浅谈C++中指针和引用的区别

    浅谈C++中指针和引用的区别 浅谈C++中指针和引用的区别   指针和引用在C++中很常用,但是对于它们之间的区别很多初学者都不是太熟悉,下面来谈谈他们2者之间的区别和用法. 1.指针和引用的定义和性 ...

  4. mkdir(): No such file or directory

    mkdir(): No such file or directory php创建目录时提示没有文件或目录, (1)先检查目录权限: (2)细看mkdir()的用法: 定义和用法: mkdir() 函数 ...

  5. 找小于N 的所有质数

    笔试题目当中,找素数出现的几率有点大.昨天就做了一个,感觉不是很难,但可以考查程序员的数学和编码功底. 用嵌套循环来实现是很理想的,怎样减少循环的次数?怎样求出小于N的所有质数? 不可能将一个数除与所 ...

  6. [原创][SW]TortoiseSVN创建本地版本控制

    1. 简介 TortoiseSVN是一个Windows平台下的Subversion用户端软件,以Windows shell extension的方式写成.它是自由软件,以GNU通用公共许可证发布.(f ...

  7. Sping、SpringMVC、SpringBoot的对比

    原文链接:https://dzone.com/articles/spring-boot-vs-spring-mvc-vs-spring-how-do-they-compare 作者: Ranga Ka ...

  8. luogu P1103 书本整理

    题目描述 Frank是一个非常喜爱整洁的人.他有一大堆书和一个书架,想要把书放在书架上.书架可以放下所有的书,所以Frank首先将书按高度顺序排列在书架上.但是Frank发现,由于很多书的宽度不同,所 ...

  9. Codeforces A. Bear and Big Brother

    ...不行.这题之后.不做1000分以下的了.很耻辱   A. Bear and Big Brother time limit per test 1 second memory limit per t ...

  10. mc

    Description 小C在MC里有n个牧场,自西向东呈一字形排列(自西向东用1-n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站, 每个牧场上只能建立一个控制站,每个控 ...