写在前面

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. Python 动态添加类方法

    习题: 1. Shape基类,要求所有子类都必须提供面积的计算,子类有三角形.矩形.圆. 2. 上题圆类的数据可序列化 第一种方法:使用Mixin多继承组合的方式,混入其它类的属性和方法 第二种方法: ...

  2. Entity Framework——常见报错总结

    1 实体属性配置为IsRequired()对更新的影响 抛出异常类型DbEntityValidationException 表结构: 实体: public class User { public in ...

  3. 提高运维效率(二)桌面显示IP

    运维人员远控电脑询问IP时,总要告诉用户找ip的步骤,岂不很烦? 以下方法直观地把ip地址显示在桌面上,再做个入职培训,即可提高运维效率. 1.  下载bginfo.exe软件,放到域控下的netlo ...

  4. shiro入门示例

    一.pom引入maven依赖 <dependencies> <dependency> <groupId>junit</groupId> <arti ...

  5. 关于String中的不变模式

    不变模式 不变模式就是为了尽可能的去除并行中的同步操作,提高并行程序的性能,可以使用一种不可改变的对象,依靠对象的不变性,可以确保其在没有同步操作的多线程环境中依然始终保持内部状态的一致性和正确性.并 ...

  6. SxsTrace程序追踪 && 错误信息分析

    先贴错误:应用程序无法运行,并行配置不正确 ,使用命令行sxstrace.exe.百度解决版本. 起因:同事给我一 EXE,然后基于 其进行开发 dll和模块,但是无法加入进程,无法运行. SxsTr ...

  7. Mybatis分页插件PageHelper简单使用

    一个好的讲解mybatis的博客地址http://www.jianshu.com/nb/5226994 引言 对于使用Mybatis时,最头痛的就是写分页,需要先写一个查询count的select语句 ...

  8. TCP/IP协议栈 -----链路层

    这节说一下链路层和ARP RARP协议 链路层: 在协议栈中链路层的目的有三个:1. 为IP模块发送或接受数据包 2.为ARP模块发送或接受ARP请求 3. 为RARP模块发送或接受RARP请求. 让 ...

  9. Go语言教程5 if switch select

    首先您需要有php或是c的基础. 否则可能看不明白 方法如下 if 表达式{ //需要注意的是  没有括号. 没错. 没有括号 比如  if  1>2 {}else{} } else { } s ...

  10. php银联网页支付实现方法

         本文实例讲述了php银联网页支付实现方法.分享给大家供大家参考.具体分析如下: 这里介绍的银联WAP支付功能,仅限消费功能. 1. PHP代码如下: 复制代码代码如下: <?phpna ...