写在前面

iOS在modal 或push等操作时有默认的转场动画,但有时候我们又需要特定的转场动画效果,从iOS7开始,苹果就提供了自定义转场的API,模态推送present和dismiss、导航控制器push和pop、标签控制器的控制器切换都可以自定义转场。

自定义转场动画的实现步骤如下:

1、遵循<UIViewControllerAnimatedTransitioning>协议的动画过渡管理对象,两个必须实现的方法:

    public func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval
// This method can only be a nop if the transition is interactive and not a percentDriven interactive transition.
public func animateTransition(transitionContext: UIViewControllerContextTransitioning)
// This is a convenience and if implemented will be invoked by the system when the transition context's completeTransition: method is invoked.
optional public func animationEnded(transitionCompleted: Bool)

2、继承于UIPercentDrivenInteractiveTransition的手势过渡管理对象,动画的过程是通过百分比控制的。如果不需要手势控制,这一步可不实现。

UIViewControllerInteractiveTransitioning {

    // This is the non-interactive duration that was returned when the
// animators transitionDuration: method was called when the transition started.
public var duration: CGFloat { get } // The last percentComplete value specified by updateInteractiveTransition:
public var percentComplete: CGFloat { get } // completionSpeed defaults to 1.0 which corresponds to a completion duration of
// (1 - percentComplete)*duration. It must be greater than 0.0. The actual
// completion is inversely proportional to the completionSpeed. This can be set
// before cancelInteractiveTransition or finishInteractiveTransition is called
// in order to speed up or slow down the non interactive part of the
// transition.
public var completionSpeed: CGFloat // When the interactive part of the transition has completed, this property can
// be set to indicate a different animation curve. It defaults to UIViewAnimationCurveEaseInOut.
// Note that during the interactive portion of the animation the timing curve is linear.
public var completionCurve: UIViewAnimationCurve // These methods should be called by the gesture recognizer or some other logic
// to drive the interaction. This style of interaction controller should only be
// used with an animator that implements a CA style transition in the animator's
// animateTransition: method. If this type of interaction controller is
// specified, the animateTransition: method must ensure to call the
// UIViewControllerTransitionParameters completeTransition: method. The other
// interactive methods on UIViewControllerContextTransitioning should NOT be
// called. public func updateInteractiveTransition(percentComplete: CGFloat)
public func cancelInteractiveTransition()
public func finishInteractiveTransition()

3、成为相应的代理,实现UIViewControllerAnimatedTransitioning的代理方法,返回我们前两步自定义的对象。

模态推送实现的代理方法

@available(iOS 2.0, *)
optional public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? @available(iOS 2.0, *)
optional public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? optional public func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? optional public func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? @available(iOS 8.0, *)
optional public func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController?

转场动画Demo

下面直接看demo,封装自定义的转场动画实现图片在两个控制器间放大过渡的动画效果,面向协议进行开发,使用时将转场动画代理设置为SZAnimator。

import UIKit
protocol SZAnimatorPresentDelegate: NSObjectProtocol { // 负责提供弹出动画的视图
func presentView() -> UIView
func presentFrameRect() -> CGRect
func presentToRect() -> CGRect
} protocol SZAnimatorDimissDelegate: NSObjectProtocol { // 负责提供dismiss动画的视图
func dismissView() -> UIView
func dismissFrameRect() -> CGRect
func dismissToRect() -> CGRect
} class SZAnimator: NSObject {
var isPresent: Bool = true
weak var presentDelegate: SZAnimatorPresentDelegate?
weak var dismissDelegate: SZAnimatorDimissDelegate?
} extension SZAnimator: UIViewControllerTransitioningDelegate { // 指定弹出时,处理动画的对象
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresent = true
return self
} // 指定弹下去时候, 处理动画的对象
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresent = false
return self
}
} // 消失动画
// 弹出动画
extension SZAnimator: UIViewControllerAnimatedTransitioning { // 返回动画的时间
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 2.0
} // 在这里, 实现真正的弹出, 或者消失的动画
// transitionContext
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
isPresent ? present(transitionContext) : dismiss(transitionContext)
} func dismiss(transitionContext: UIViewControllerContextTransitioning) { // 自定义动画
// 面向协议进行开发
// 1. 拿什么界面做动画
// 2. fromRect
// 3. toRect let animationView = dismissDelegate!.dismissView()
transitionContext.containerView()?.addSubview(animationView) // 初始的frame
animationView.frame = dismissDelegate!.dismissFrameRect()
// 最终需要展示的视图
if #available(iOS 8.0, *) {
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey) // 动画
UIView.animateWithDuration(transitionDuration(transitionContext), animations: {
// toView?.alpha = 1
animationView.frame = self.dismissDelegate!.dismissToRect()
fromView?.alpha =
}) { (flag: Bool) in
animationView.removeFromSuperview()
transitionContext.completeTransition(true)
}
}
} func present(transitionContext: UIViewControllerContextTransitioning) {
// 自定义动画
// 面向协议进行开发
// 1. 拿什么界面做动画
// 2. fromRect
// 3. toRect let animationView = presentDelegate!.presentView()
transitionContext.containerView()?.addSubview(animationView) // 初始的frame
animationView.frame = presentDelegate!.presentFrameRect() // 最终需要展示的视图
if #available(iOS 8.0, *) {
let toView = transitionContext.viewForKey(UITransitionContextToViewKey) toView?.frame = UIScreen.mainScreen().bounds
transitionContext.containerView()?.addSubview(toView!)
toView?.alpha = // 动画
UIView.animateWithDuration(2.0, animations: {
toView?.alpha =
animationView.frame = self.presentDelegate!.presentToRect()
}) { (flag: Bool) in animationView.removeFromSuperview()
transitionContext.completeTransition(true)
}
}
}
}

iOS转场动画封装的更多相关文章

  1. iOS_SN_push/pop转场动画封装和一般动画封装

    封装类中的方法: #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface AnimationE ...

  2. iOS 转场动画探究(一)

    什么是转场动画: 转场动画说的直接点就是你常见的界面跳转的时候看到的动画效果,我们比较常见的就是控制器之间的Push和Pop,还有Present和Dismiss的时候设置一下系统给我们的modalTr ...

  3. iOS 转场动画探究(二)

    这篇文章是接着第一篇写的,要是有同行刚看到的话建议从前面第一篇看,这是第一篇的地址:iOS 转场动画探究(一) 接着上一篇写的内容: 上一篇iOS 转场动画探究(一)我们说到了转场要素的第四点,把那个 ...

  4. iOS转场动画

    文顶顶 最怕你一生碌碌无为 还安慰自己平凡可贵 iOS开发UI篇—核心动画(转场动画和组动画) iOS开发UI篇—核心动画(转场动画和组动画) 一.转场动画简单介绍 CAAnimation的子类,用于 ...

  5. iOS - 转场动画

    苹果在 iOS7 定制了 ViewController 的切换效果 一 在iOS5和iOS6之前,ViewController的切换主要有4种 Push/Pop,NavigationViewCotnr ...

  6. iOS 转场动画核心内容

    CATransition——转场动画 CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果.iOS比Mac OS X的转场动画效果少一点. ...

  7. iOS转场动画初探

    一般我们就用两种转场push和present present /** 1.设置代理 - (instancetype)init { self = [super init]; if (self) { se ...

  8. IOS 转场动画二和透明控制器视图

    一.透明视图控制器 WJListMenuViewController *VC = [[WJListMenuViewController alloc]init]; VC.modalPresentatio ...

  9. UIView封装动画--iOS利用系统提供方法来做转场动画

    UIView封装动画--iOS利用系统提供方法来做转场动画 UIViewAnimationOptions option; if (isNext) { option=UIViewAnimationOpt ...

随机推荐

  1. laravel webpack填坑(陆续更)

    ie Promise支持需引入babel-polyfill, 在官方文档中js函数介绍有点少导致按babel-polyfill官方引入时找不到北 //webpack.mix.jsmix.js(['no ...

  2. Vim常用操作-合并行。

    刚接触 Vim 会觉得它的学习曲线非常陡峭,要记住很多命令.所以这个系列的分享,不会教你怎么配置它,而是教你怎么快速的使用它. 在开发时为了代码美观,经常会把属性用换行的方式显示. <el-di ...

  3. php代码中的细节问题

    本次主要谈及工作中关于注销功能中的路径设置及session的清除问题之前的调试一直忽略了session的功能,以至于每次使用__ROOT__/index.php/home/Student/logout ...

  4. 机器学习算法 - 最近邻规则分类KNN

    上节介绍了机器学习的决策树算法,它属于分类算法,本节我们介绍机器学习的另外一种分类算法:最近邻规则分类KNN,书名为k-近邻算法. 它的工作原理是:将预测的目标数据分别跟样本进行比较,得到一组距离的数 ...

  5. C# 中枚举的一点研究(跳过一些net坑的研究而已)

    之前一直使用Enum.Parse()将字符串转为枚举,没有深究,后面发现一个问题后对下面的Enum有了一个初步研究(.net 4.0).看下面代码. (留意,枚举类型是值类型,其值不能为Null,所以 ...

  6. warning: C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失

    ------问题-------------------- Qt项目使用 VC++ 编译器出现此错误. warning: C4819: 该文件包含不能在当前代码页(936)中表示的字符.请将该文件保存为 ...

  7. 整合SSH时,遇到了org.springframework.beans.factory.BeanCreationException错误

    严重: StandardWrapper.Throwableorg.springframework.beans.factory.BeanCreationException: Error creating ...

  8. 04.redis集群+SSM整合使用

    redis集群+SSM整合使用 首先是创建redis-cluster文件夹: 因为redis最少需要6个节点(三主三从),为了更好的理解,我这里创建了两台虚拟机(192.168.0.109 192.1 ...

  9. 第四届河南省ACM 表达式求值 栈

    表达式求值 时间限制: 1 Sec  内存限制: 128 MB 提交: 14  解决: 7 [提交][状态][讨论版] 题目描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简 ...

  10. PHP的AES加密类

    PHP的AES加密类 aes.php <?php /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ...