最近学习了一下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. Maven-在eclipse中安装Maven插件

    装IDE Plugins的方法有很多. 其一:在线安装 通过Help-->Install New Software的方式,输入HTTP地址来安装,简单易操作,但是也优缺点,就是下载速度慢,或者有 ...

  2. [Asp.net mvc] Asp.net mvc Kendo UI Grid的使用(四)

    有段时间没写博客了,工作状态比较忙,抽空继续总结下Grid的使用,这次主要介绍模板以及其他官网介绍不详尽的使用方法.先Show出数据,然后讲解下.后台代码: public ActionResult O ...

  3. 轻量级应用开发之(06)Autolayout自动布局1

    一 什么是Autolayout Autolayout是一种“自动布局”技术,专门用来布局UI界面的. 自IOS7 (Xcode 5)开始,Autolayout的开发效率得到很大的提高. 苹果官方也推荐 ...

  4. EasyUI datagrid 格式化显示数据

    http://blog.163.com/ppy2790@126/blog/static/103242241201512502532379/ 设置formatter属性,是一个函数,格式化函数有3个参数 ...

  5. 依赖管理工具漫谈--从Maven,Gradle到Go

    http://jolestar.com/dependency-management-tools-maven-gradle/

  6. mac 下终端访问文件出现“Permission Denied”解决方案

    mac 下终端访问文件出现“Permission Denied”解决方案: 一个文件有3种权限,读.写.可执行,你这个文件没有可执行权限,需要加上可执行权限. 1. 终端下先 cd到该文件的目录下 2 ...

  7. DAO,Service,Controller各层之间的关系

    DAO层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口 ...

  8. TCP/IP协议栈概述

    TCP/IP协议栈概述 这篇文章虽然只是很粗浅的介绍了ISO/OSI 网络模型,但确实把握住了关键点,某种意义上,简单回顾一下就可以加深对TCP/IP协议栈的理解. 原作者:阮一峰 链接: http: ...

  9. C#多线程学习 之 线程池[ThreadPool](转)

    在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPo ...

  10. git windows中文目录乱码问题解决

    转自:http://blog.chinaunix.net/uid-9789774-id-3080448.html Git的Windows版本Msysgit对中文的支持不够好 当使用时,会出现以下三种情 ...