最近学习了一下ios7比较重要的一项功能,就是 controller 的 custom transition。

在ios7中,navigation controller 中就使用了交互式过渡来返回上级界面,可以通过设置interactivePopGestureRecognizer.enabled 来关闭这个效果。

请参阅 ,写的非常好,建议2篇文章都要读读

http://onevcat.com/2013/10/vc-transition-in-ios7/

http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/

我测试用的是modelview 的present 和dismiss,没有试验navigationController的push,pop,和tabbarController的选择.


先说说在实现non-interactive动画时,遇到的问题。

在写demo时,用了controller.modalPresentationStyle = UIModalPresentationCustom;  就无法在- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext函数中通过toViewController.frame 获得 frame了,全是0,开始想不通,后来发现,之所以不用UIModalPresentationCustom时,可以获得frame,是因为系统通过modalPresentationStylez为toViewController.frame设定了初始值,而用了UIModalPresentationCustom,系统就不管toViewController.frame的初始化了,自然要自己指定frame了!这也才是custom的意义,自定义弹出开始和结束时的frame。另外还有一个问题,如果使用了controller.modalPresentationStyle = UIModalPresentationCustom,并且屏幕经过了旋转90度,transitionContext的containerView的坐标系并不会一起旋转,结果就是,先旋转,再present出controller,那么controller的frame就错了。

但是如果不使用UIModalPresentationCustom,而使用其他的style(在ipad上测试),同时使用自定义动画,要么会产生视图bug(UIModalPresentationFormSheet和UIModalPresentationPageSheet),要么还是像以前一样,会把原来controller的view从hierarchy上移掉(UIModalPresentationFullScreen,UIModalPresentationNone)!就达不到同时现实2个controller的view的效果了。如果仅仅想更改动画效果,不需要2个controller同时出现,那么不应该使用UIModalPresentationCustom。如果使用了UIModalPresentationCustom,那么就需要针对屏幕的各个方向,调整自定义动画的start frame 和 end frame。比如需要支持4个方向,那么就需要4组start frame 和 end frame,这样才能达到不同方向,相同的弹出效果。


再说说实现interactive动画时,遇到的问题。

由于要支持交互,view的中间坐标变换实现比较复杂,为了简化编码工作,苹果提供了一个类:UIPercentDrivenInteractiveTransition,这个类实现了UIViewControllerInteractiveTransitioning

接口的startInteractiveTransition方法,并且提供了3个简便的控制函数,

- (void)updateInteractiveTransition:(CGFloat)percentComplete;  //根据percentComplete自动更新动画,可以自己重写

- (void)cancelInteractiveTransition; //取消过渡,返回过渡之前的状态,可以自己重写

- (void)finishInteractiveTransition; //完成过渡,达到过渡后的状态,可以自己重写

这样,实现一个交互的transition便简单了,你只需要在interactionControllerForPresentation这个代理方法中提供一个UIPercentDrivenInteractiveTransition对象A,系统会把这个对象A和UIViewControllerTransitioningDelegate对象相关联,当A对象在手势处理等方法中被发送updateInteractiveTransition等消息时,A对象会通过UIViewControllerTransitioningDelegate对象中实现的non-interactive动画 和 自己的percentComplete来自动计算具体的view的显示效果并予以显示(This style of interaction controller should only be used with an animator that implements a CA style transition in the animator's animateTransition: method.),当然,你也可以不实现non-interactive动画,而重写startInteractiveTransition等4个函数,也能实现想要的效果,但是对于复杂的变化,view的计算会很复杂!所以,建议实现animateTransition:方法。

观察UIViewControllerInteractiveTransitioning协议,只有一个必须实现的代理函数startInteractiveTransition,其实这个函数的主要目的,就是在交互开始时,能够把对应的transitionContext传递给编程人员,对transitionContext进行设置,比如添加view[containerView addSubview:[toCollectionViewController view]]; 或者保存transitionContext的引用,以便在其他函数中,通过调用transitionContext的updateInteractiveTransition,finishInteractiveTransition,cancelInteractiveTransition 进行交互操作。(id <UIViewControllerContextTransitioning>)transitionContext才是交互式过渡的主角。

另外,如果在返回UIViewControllerInteractiveTransitioning的代理中返回了对象,那么系统会认为你要使用交互式的过渡,在相应的过渡发生时,自动调用startInteractiveTransition,如果不想startInteractiveTransition被调用,要在代理方法中返回nil。


再简要的总结一下,主要分3步。

第一,要有一个UIViewControllerTransitioningDelegate,这个代理会为相应的controller提供4个用于过渡的对象,

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController: //提供non-interaction的present动画对象

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed;//提供non-interaction的dismiss动画对象

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator; //提供interaction的present的动画对象

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator;//提供interaction的dismiss动画对象

第二,需要创建这4个对象,对于non-interaction的情况(前2个代理函数),要创建一个实现实现UIViewControllerAnimatedTransitioning的类,并实现animateTransition方法。对于interaction的情况(后两个代理函数),最好不创建实现UIViewControllerInteractiveTransitioning的类,直接使用UIPercentDrivenInteractiveTransition类。

第三,如果要使用interaction的transition,还需要多做一步,就是在view上加载gesture,并在gesture的代理函数中不断调用 UIPercentDrivenInteractiveTransition 的 updateInteractiveTransition来更新动画。


另外,当使用在UINavigationController中使用2个UICollectionViewController进行导航时,可以通过设置UICollectionViewController对象的useLayoutToLayoutNavigationTransitions属性,设置正确后,navigation controller在这2个controller之间导航时就不会使用默认的左右滑动,而会把layout的变化应用为动画,来体现push和pop。具体效果和实现,请参与苹果demo :Collection View Transition,效果很炫。如果需要把这种transition做成interactive的,那么需要更多复杂工作,因为这里涉及了navigation,和 collection中的各个subview的过渡,与collectionView 过渡相关的函数也很杂乱,请参考demo中的代码。

iOS 定制controller过渡动画 ViewController Custom Transition使用体会的更多相关文章

  1. 基于 React 实现一个 Transition 过渡动画组件

    过渡动画使 UI 更富有表现力并且易于使用.如何使用 React 快速的实现一个 Transition 过渡动画组件? 基本实现 实现一个基础的 CSS 过渡动画组件,通过切换 CSS 样式实现简单的 ...

  2. CSS3过渡动画&关键帧动画

    一.过渡动画 过渡(transition)动画,就是从初始状态过渡到结束状态这个过程中所产生的动画. 所谓的状态就是指大小.位置.颜色.变形(transform)等等这些属性. Note:不是所有属性 ...

  3. iOS学习笔记-自定义过渡动画

    代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...

  4. [iOS]过渡动画之高级模仿 airbnb

    注意:我为过渡动画写了两篇文章:第一篇:[iOS]过渡动画之简单模仿系统,主要分析系统简单的动画实现原理,以及讲解坐标系.绝对坐标系.相对坐标系,坐标系转换等知识,为第二篇储备理论基础.最后实现 Ma ...

  5. wp8.1 Study8:页面过渡和主题动画(Page transition and Theme animations)

    一.在WP8.1中是有动画(Animation)的: 页面导航(默认为旋转式Turnstile).PointerDown/up(默认是倾斜).页面旋转.MenuFlyout出现等等 二.页面过渡(Pa ...

  6. transition过渡动画

    过渡动画必须写在<transition></transition>标签内,配合其他标签使用. 例子: <transition name="fade" ...

  7. iOS 7 UI 过渡指南 - 開始之前(iOS 7 UI Transition Guide - Before You Start)

    iOS 7 UI Transition Guide Preparing for Transition Before You Start Scoping the Project Supporting i ...

  8. 067——VUE中vue-router之使用transition设置酷炫的路由组件过渡动画效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 定制controller转场动画

    定制controller转场动画 从iOS7开始就可以自由定制控制器间的转场动画了,以下实例描述最简单的定制方式,达到的效果如下所示: 为了实现这个效果需要这么多的文件-_-!!!! RootView ...

随机推荐

  1. WeakHashMap和HashMap的区别

    看Java源码的时候,看到了 WeakHashMap ,我一直以来使用的 都是 HashMap,于是查了一下两者的区别 (一) 查看API文档,WeakHashmap要点如下: 1. 以弱键 实现的基 ...

  2. selenium常见的疑问和问题

    .确认(verifation)和断言(assert)有什么区别?  确认:当测试中的一个用例存在错误时,系统将会继续运行这些测试  断言:当测试中的一个用例存在错误时,系统将会退出当前用例  总而言之 ...

  3. 【POJ 3020】Antenna Placement(二分图匹配)

    相当于用1*2的板覆盖给定的h*w的格子里的点,求最少的板.可以把格子相邻的分成两个集合,如下图,0为一个集合,1的为一个,也就是(行数+列数)为奇数的是一个集合,为偶数的为另一个集合.1010101 ...

  4. 45.Android 第三方开源库收集整理(转)

    原文地址:http://blog.csdn.net/caoyouxing/article/details/42418591 Android开源库 自己一直很喜欢Android开发,就如博客签名一样,  ...

  5. RegexBuddy正则表达式工具

    RegexBuddy非常的好用,而且还能生成.net的代码. 我们在使用正则匹配时,毕竟.net提供的方法中,对于多行匹配就不能用单纯的正则去实现,而我们需要把它转换成相应的类库方法进行实现. 那么R ...

  6. debian , ubuntu 截取下拉菜单

    普通情况下print键很好用的,但是,截下拉菜单的时候,就怎么按都没反应了...然后换了shutter也不行,只能在静态界面截图.所以...然后就有了下面方法. 如果不是gnome怎么办?这个担心显然 ...

  7. 最短路之Dijkstra算法

    1. 邻接矩阵 int cost[MAX_V][MAX_V]; //assume cost[u][v]>0 int d[MAX_V]; bool used[MAX_V]; void Dijkst ...

  8. android4.0浏览器在eclipse中编译的步骤

    工程源码: 注意: 如果下载已经修过的源码,只要进行3.4.8步骤就应该可以了. eclipse版本:adt-bundle-windows (Android Developer Tools Build ...

  9. Core Animation编程指南

    本文是<Core Animation Programming Guide>2013-01-28更新版本的译文.本文略去了原文中关于OS X平台上Core Animation相关内容.因为原 ...

  10. POJ2392Space Elevator(贪心+背包)

    Space Elevator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9970   Accepted: 4738 De ...