最近学习了一下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. meta之renderer

    今天不小心看了下慕课网首页的源码,看到有一行 1 <meta name="renderer" content="webkit|ie-comp|ie-stand&qu ...

  2. 【UESTC 482】Charitable Exchange(优先队列+bfs)

    给你n个物品交换,每个交换用r,v,t描述,代表需要用r元的东西花费t时间交换得v元的东西.一开始只有1元的东西,让你求出交换到价值至少为m的最少时间代价.相当于每个交换是一条边,时间为边权,求走到价 ...

  3. C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

    目录 . 引言 . 交叉编译 . Cygwin简介 . 静态库编译及使用 . 动态库编译及使用 . MinGW简介 . CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件 ...

  4. RIP、OSPF、BGP、动态路由选路协议、自治域AS

    相关学习资料 tcp-ip详解卷1:协议.pdf http://www.rfc-editor.org/rfc/rfc1058.txt http://www.rfc-editor.org/rfc/rfc ...

  5. 连通性1 求无向图的low值

    这是DFS系列的第一篇 . 首先给出一个重要的定理.该定理来自<算法导论>. An undirected graph may entail some ambiguity in how we ...

  6. SCU 4424(求子集排列数)

    A - A Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice ...

  7. android经典实战项目视频教程下载

    注:这是一篇转载的文章,原文具体链接地址找不到了,将原文分享如下,希望能对看到的朋友有所帮助! 最近在学习android应用方面的技术,自己在网上搜集了一些实战项目的资料,感觉挺好的,发布出来跟大伙分 ...

  8. Spring学习8-Spring事务管理(编程式事务管理)

    一.Spring事务的相关知识   1.事务是指一系列独立的操作,但在概念上具有原子性. 比如转账:A账号-100, B账号+100,完成.这两个操作独立是没问题的. 但在逻辑上,要么全部完成,要么一 ...

  9. JSP 使用

    JSP教程: http://www.w3cschool.cc/jsp/jsp-tutorial.html jsp语法: 任何语言都有自己的语法,JAVA中有,JSP虽然是在JAVA上的一种应用,但是依 ...

  10. 使用 array_multisort 对多维数组排序

    array_multisort() 函数对多个数组或多维数组进行排序. 用法详看:http://www.w3school.com.cn/php/func_array_multisort.asp 例子: ...