iOS 定制controller过渡动画 ViewController Custom Transition使用体会
最近学习了一下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使用体会的更多相关文章
- 基于 React 实现一个 Transition 过渡动画组件
过渡动画使 UI 更富有表现力并且易于使用.如何使用 React 快速的实现一个 Transition 过渡动画组件? 基本实现 实现一个基础的 CSS 过渡动画组件,通过切换 CSS 样式实现简单的 ...
- CSS3过渡动画&关键帧动画
一.过渡动画 过渡(transition)动画,就是从初始状态过渡到结束状态这个过程中所产生的动画. 所谓的状态就是指大小.位置.颜色.变形(transform)等等这些属性. Note:不是所有属性 ...
- iOS学习笔记-自定义过渡动画
代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...
- [iOS]过渡动画之高级模仿 airbnb
注意:我为过渡动画写了两篇文章:第一篇:[iOS]过渡动画之简单模仿系统,主要分析系统简单的动画实现原理,以及讲解坐标系.绝对坐标系.相对坐标系,坐标系转换等知识,为第二篇储备理论基础.最后实现 Ma ...
- wp8.1 Study8:页面过渡和主题动画(Page transition and Theme animations)
一.在WP8.1中是有动画(Animation)的: 页面导航(默认为旋转式Turnstile).PointerDown/up(默认是倾斜).页面旋转.MenuFlyout出现等等 二.页面过渡(Pa ...
- transition过渡动画
过渡动画必须写在<transition></transition>标签内,配合其他标签使用. 例子: <transition name="fade" ...
- 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 ...
- 067——VUE中vue-router之使用transition设置酷炫的路由组件过渡动画效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 定制controller转场动画
定制controller转场动画 从iOS7开始就可以自由定制控制器间的转场动画了,以下实例描述最简单的定制方式,达到的效果如下所示: 为了实现这个效果需要这么多的文件-_-!!!! RootView ...
随机推荐
- MyEclipse 开发 Web项目发布到 Tomcat 下的Root 目录
通常情况下,Web项目是发布到Tomcat下的webapps文件目录下的 . 例如:Web应用项目名称为:stock,则部署到tomcat后,是部署在tomcat/webapps/stock中,网址为 ...
- 【CodeForces 622A】Infinite Sequence
题意 一个序列是, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5....这样排的,求第n个是什么数字. 分析 第n个位置属于1到k,求出k,然后n-i*(i-1)/ ...
- BIEE 仪表盘的创建
1.新建仪表盘 选择共享文件夹里创建的表拖到仪表盘中 保存并运行 也可以新建更多仪表盘页 2.新建仪表盘提示 把提示和表都拖到仪表盘中 3.主从关系:第二张表的结果页面 ——>编辑视图——&g ...
- WebLogic10安装图文教程
一 WebLogic安装 1. 打开WebLogic安装程序:oepe11_wls1031.exe(我们选用的是WebLogic 10.3g).如图1-1所示: 2. 进入WebLogic安装的欢迎 ...
- BZOJ1432 [ZJOI2009]Function
Description Input 一行两个整数n; k. Output 一行一个整数,表示n 个函数第k 层最少能由多少段组成. Sample Input 1 1 Sample Output 1 H ...
- POJ1737 Connected Graph
Connected Graph Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3156 Accepted: 1533 D ...
- POJ 2240Arbitrage(Floyd)
E - Arbitrage Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submi ...
- Laravel教程 五:MVC的基本流程
Laravel教程 五:MVC的基本流程 此文章为原创文章,未经同意,禁止转载. Controller 期间受到很多私事影响,终于还是要好好写写laravel的教程了. 上一篇我们说了数据库和Eloq ...
- xampp 安装red扩展出错解决
Linux Mint + Xampp Error + ‘grep: /opt/lampp/include/php/main/php.h: No Such File Or Directory’ FEBR ...
- hdu 1284 钱币兑换问题(动态规划)
Ac code : 完全背包: #include<stdio.h> #include<string.h> int dp[4][40000]; int main(void) { ...