写在前面

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. 我从.net转到java的心得和体会

    前言:由于有不少人咨询过我如果从.net转java,有什么技巧吗,我现在就分享我从.net转java的历程,这里不涉及两门语言的比较,记录的都是我个人的观点. 一:从.net转java的初衷 我是20 ...

  2. 用python画一朵玫瑰花

    废话不多说,直接上代码 from turtle import * import time setup(600,800,0,0) speed(0) penup() seth(90) fd(340) se ...

  3. vim编辑器介绍及其常用命令

    vim简单的介绍 Vim 编辑器是一个模式编辑器 . 这意味着在不同状态下编辑器有不同的行为模式 . 两个基本的模式是 Normal 模式和 Insert 模式 ,还有可视模式. 在 Normal 模 ...

  4. 前端学习记录之Javascript-DOM

    简介 为了快捷方便,在工作和项目中,一直都是使用的框架,比如jqeruy,vuejs,react等.然后在长时间使用框架后,往往有一个后遗症,就是对于原生的Javascript基本上已经不知道怎么写了 ...

  5. Mac下面的SecureCRT以及破解方案详解

    今天安装SecureCRT时遇到了一些问题,解决后便想分享给大家.本人还是在校大学生,如果有说得不好的地方请多多指教. 第一步:下载:https://macabc.com/detail.htm?app ...

  6. 【深圳】大湾区第三次.NET技术交流会(网络直播)

    活动简介 云.devops.微服务.容器是现在这个发展阶段的软件形态, 本次活动我们围绕这些话题介绍.NET生态下的发展.SQL Server 2017可根据需要运行本地部署的SQL Server,当 ...

  7. 照虎画猫写自己的Spring——自定义注解

    Fairy已经实现的功能 读取XML格式配置文件,解析得到Bean 读取JSON格式配置文件,解析得到Bean 基于XML配置的依赖注入 所以,理所当然,今天该实现基于注解的依赖注入了. 基于XML配 ...

  8. Git版本控制器的使用

    首先介绍一下什么是Git:git是目前最流行的版本控制系统,属于分布式版本控制器. 使用Git前先要在GitHub创建代码仓库,或者获取你要应用的GitHub的链接地址. 创建GitHub仓库这里就不 ...

  9. js 数组去重复的方法

    数组去重复是js中常用的方法,归纳了四种如下: 1. for + indexOf  去重复 var arr = [3,5,5,4,1,1,2,3,7,2,5]; var target = []; fo ...

  10. javascript算法题判断输入年份是否是闰年

    用户输入一个年份,判断这个年是否是闰年.判断闰年条件:① 非整百年数除以4,无余为闰,有余不闰:② 整百年数除以400,无余为闰,有余不闰.比如:2000年,整百数年,就要用②公式,除以400,无余数 ...