iOS - 转场动画
苹果在 iOS7 定制了 ViewController 的切换效果
一 在iOS5和iOS6之前,ViewController的切换主要有4种
- Push/Pop,NavigationViewCotnroller常做的事儿
- Tab, TabViewController点击
- Present Modal,调用viewController的presentViewController:animated:completion:方法
- add ChildViewController,调用addChildViewController:(UIViewController *)childController方法
注意:使用第四种方式时,一般使用transitionFromViewController:toViewController:的animation block中可以实现一些简单的切换效果,这样做有2大不足:
- 代码高度耦合,vc切换部分的代码直接写在container中,难以分离重用。
- 支持的切换效果比较有限,因为其职能使用UIView动画来切换,管理起来也略显麻烦。
二 iOS7中引入一些新的api,更松耦合地定义viewController的转换效果

从上图中可看出,新的api主要提供了2中vc切换方式。
一种是动画式切换,即定义一种从一个vc到另一个vc的动画效果,切换的时候自动播放。
一种是交互式切换,这种方式同样需要定义动画效果,只是这个动画效果会跟随交互手势来切换vc并同时播放动画效果。用法略有不同。
动画式切换:
- 首先定义一个动画类实现接口 UIViewControllerAnimatedTransitioning,实现接口的2个方法,一个是动画效果,一个是动画时间。实现动画效果时可以从参数transitionContext中获取到切换时的上下文信息,比方说从哪个VC切换到哪个VC等。
- 在需切换的VC中实现UIViewControllerTransitioningDelegte,并实现animationController方法,返回一个步骤1中定义的动画变量。
- 调用展现VC切换方法,presentViewController / push等。
(1)、单独两个ViewController之间的转场(相当于以前的modal),需要第一个VC去实现 UIViewControllerTransitioningDelegate
VC -->VC (纯VC-->纯的VC、纯VC-->UINavigationVC、UINavigationVC-->纯VC、UINavigationVC-->UINavigationVC)
即 VC.transitioningDelegate 或者 UINavigationVC.transitioningDelegate
(2)、不是单独两个ViewController之间的转场,需要用一个UINavigationController去控制转场的 我们需要告知 UINavigationController 去使用 UIViewControllerAnimatedTransitioning.
1.应该让当前这个ViewController去作为UINavigationControllerDelegate的代理对
2.最好是写一个基类继承UINavigationController 在里面设置UINavigationControllerDelegate代理,对于不同的由UINavigationController去控制的转场动画做统一处理
self.delegate = self ;
- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC{ if ([toVC isKindOfClass:[SecondViewController class]]) {
MagicMoveTransition *transition = [[MagicMoveTransition alloc]init];
return transition;
}else{
return nil;
}
}
交互式切换:
- 首先定义一个动画类实现接口 UIViewControllerInteractiveTransitioning,iOS7提供了一个默认的基于百分比的动画实现UIPercentDrivenInteractiveTransition,不想太麻烦可以直接扩展这个类。该类需要绑定需要实现手势控制的VC,同时把手势操作添加到该VC上,然后在处理手势动作的时候,调用接口中的方法去更新当前的动画进度。
- 定以切换时的动画效果类。和动画式切换的方式一致。
- 在需切换的VC中实现UIViewControllerTransitioningDelegate,实现interactiveController方法,返回步骤1定义的类,实现animationController方法返回步骤2定义的动画效果。
- 一般用于响应手势做出的转场动画。
例如:在用户手指从屏幕左边边缘划入时产生互动
我们在第二个 viewController 的 viewDidLoad 方法中,创建这个手势识别器
- (void)viewDidLoad {
[super viewDidLoad];
UIScreenEdgePanGestureRecognizer *edgePanGestureRecognizer = [[UIScreenEdgePanGestureRecognizer alloc]initWithTarget:self action:@selector(edgePanGesture:)];
//设置从什么边界滑入
edgePanGestureRecognizer.edges = UIRectEdgeLeft;
[self.view addGestureRecognizer:edgePanGestureRecognizer];
}
现在我们可以识别该手势了,然后我们用它来设置并更新一个 iOS 7 新加入的类的对象。 UIPercentDrivenInteractiveTransition。这个类的对象会根据我们的手势,来决定我们的自定义过渡的完成度。我们把这些都放到手势识别器的 action 方法中去,具体就是:
-(void)edgePanGesture:(UIScreenEdgePanGestureRecognizer *)recognizer{
//计算手指滑的物理距离(滑了多远,与起始位置无关)
CGFloat progress = [recognizer translationInView:self.view].x / self.view.bounds.size.width;
progress = MIN(1.0, MAX(0.0, progress));//把这个百分比限制在0~1之间
//当手势刚刚开始,我们创建一个 UIPercentDrivenInteractiveTransition 对象
if (recognizer.state == UIGestureRecognizerStateBegan) {
self.percentDrivenTransition = [[UIPercentDrivenInteractiveTransition alloc]init];
[self.navigationController popViewControllerAnimated:YES];
}else if (recognizer.state == UIGestureRecognizerStateChanged){
//当手慢慢划入时,我们把总体手势划入的进度告诉 UIPercentDrivenInteractiveTransition 对象。
[self.percentDrivenTransition updateInteractiveTransition:progress];
}else if (recognizer.state == UIGestureRecognizerStateCancelled || recognizer.state == UIGestureRecognizerStateEnded){
//当手势结束,我们根据用户的手势进度来判断过渡是应该完成还是取消并相应的调用 finishInteractiveTransition 或者 cancelInteractiveTransition 方法.
if (progress > 0.5) {
[self.percentDrivenTransition finishInteractiveTransition];
}else{
[self.percentDrivenTransition cancelInteractiveTransition];
}
}
}
最后一步,别忘了告诉navigationController 去用它。 在SecondViewController.m 里,实现UINavigationControllerDelegate 中的另一个返回UIViewControllerInteractiveTransitioning的方法:
- (id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController{
if ([animationController isKindOfClass:[MagicMoveInverseTransition class]]) {
return self.percentDrivenTransition;
}else{
return nil;
}
}
iOS8 UIPresentationController
modal 的方式
UIPresentationController,它与 iOS 7 新添加的几个类与协议一道,帮助我们方便快捷地实现 ViewController 的自定义过渡效果。

代码:https://github.com/PeteC/PresentationControllers
UIPresentationController 的子类是负责「被呈现」及「负责呈现」的 controller 的大小 modal出来的控制器其实是在单独的一个window中里面有个容器放着被呈现的vc,可以改变view 的frame (其controller 大小也会改变)如下
- (void)containerViewWillLayoutSubviews{
[super containerViewWillLayoutSubviews];
// 1.设置弹出View的尺寸
[self presentedView].frame = self.presentedFrame;
// 2.添加蒙版
[self setupCoverView];
}
当然它还可以负责的仅仅是那个带渐变效果的红色的半透明背景 View 的动画(其实是我们自己加进去一个view 然后根据监听弹出的的过程对改view做动画)
* presentationTransitionWillBegin //是在呈现过渡即将开始的时候被调用的
* presentationTransitionDidEnd: //是在呈现过渡结束时被调用的
* dismissalTransitionWillBegin
* dismissalTransitionDidEnd:
* frameOfPresentedViewInContainerView// 重写返回PresentedView的frame
http://www.cocoachina.com/industry/20140707/9053.html
http://www.kittenyang.com/uipresentation/
iOS - 转场动画的更多相关文章
- iOS 转场动画探究(一)
什么是转场动画: 转场动画说的直接点就是你常见的界面跳转的时候看到的动画效果,我们比较常见的就是控制器之间的Push和Pop,还有Present和Dismiss的时候设置一下系统给我们的modalTr ...
- iOS 转场动画探究(二)
这篇文章是接着第一篇写的,要是有同行刚看到的话建议从前面第一篇看,这是第一篇的地址:iOS 转场动画探究(一) 接着上一篇写的内容: 上一篇iOS 转场动画探究(一)我们说到了转场要素的第四点,把那个 ...
- iOS转场动画
文顶顶 最怕你一生碌碌无为 还安慰自己平凡可贵 iOS开发UI篇—核心动画(转场动画和组动画) iOS开发UI篇—核心动画(转场动画和组动画) 一.转场动画简单介绍 CAAnimation的子类,用于 ...
- iOS转场动画封装
写在前面 iOS在modal 或push等操作时有默认的转场动画,但有时候我们又需要特定的转场动画效果,从iOS7开始,苹果就提供了自定义转场的API,模态推送present和dismiss.导航控制 ...
- iOS 转场动画核心内容
CATransition——转场动画 CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果.iOS比Mac OS X的转场动画效果少一点. ...
- iOS转场动画初探
一般我们就用两种转场push和present present /** 1.设置代理 - (instancetype)init { self = [super init]; if (self) { se ...
- IOS 转场动画二和透明控制器视图
一.透明视图控制器 WJListMenuViewController *VC = [[WJListMenuViewController alloc]init]; VC.modalPresentatio ...
- iOS开发UI篇—核心动画(转场动画和组动画)
转自:http://www.cnblogs.com/wendingding/p/3801454.html iOS开发UI篇—核心动画(转场动画和组动画) 一.转场动画简单介绍 CAAnimation的 ...
- iOS 开发--转场动画
"用过格瓦拉电影,或者其他app可能都知道,一种点击按钮用放大效果实现转场的动画现在很流行,效果大致如下:" 本文主讲SWIFT版,OC版在后面会留下Demo下载 在iOS中,在同 ...
随机推荐
- Spring面试,IoC和AOP的理解
spring 的优点?1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易实 ...
- (笔记)Linux下怎么安装tar.gz的软件
一般这种的就是源代码.先下载下来.然后cd到下载目录.用tar xvfz XXX.tar.gz的解压.然后进入解压后的目录. 打./configure生成配置文件.打make对源代码进行编译,生成库和 ...
- Python中的高级turtle(海龟)作图
在Python里,海龟不仅可以画简单的黑线,还可以用它画更复杂的几何图形,用不同的颜色,甚至还可以给形状填色. 一.从基本的正方形开始 引入turtle模块并创建Pen对象: >>> ...
- js 正则去重
split():字符串中的方法,把字符串转成数组. sort():数组中的排序方法,按照ACALL码进行排序. join():数组中的方法,把数组转换为字符串 var demo="ababb ...
- 10个样式各异的CSS3 Loading加载动画
前几天我在园子里分享过2款很酷的CSS3 Loading加载动画,今天又有10个最新的Loading动画分享给大家,这些动画的样式都不一样,实现起来也并不难,你很容易把它们应用在项目中,先来看看效果图 ...
- python pip 更换国内安装源(windows)
1.点击此电脑,在最上面的的文件夹窗口输入 : %APPDATA% 2.按回车跳转到以下目录,新建pip文件夹 3.创建pip.ini文件 4.打开文件夹,输入以下内容,关闭即可(注意:源镜像可替换) ...
- ZeroClipboard插件——复制到剪切板
ZeroClipboard是一个轻量级的jQuery“复制到剪贴板”插件采用了时下流行的零剪贴板库.官网:http://www.steamdev.com/zclip 参数及默认值path(必选) Z ...
- SOA及分布式
结合领域驱动设计的SOA分布式软件架构 Windows平台分布式架构实践 - 负载均衡(下) 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载 我终于深入参与了一 ...
- Android立刻终止一个线程
/** * Created by JuTao on 2017/2/4. * 如何中止一个线程 */ public class ThreadDone { public static void main( ...
- 史上最全的 Sublime Text 汉化、插件安装合集
0.前言 本文用于给新手小白用户指明前进方向.不用做商业推广. 其次,鼓舞购买正版.拒绝盗版. 好了.口号喊完,接下来就直接開始正文. 1. Sublime Text 介绍 首先在開始前,先来介绍一下 ...