iOS转场动画封装
写在前面
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转场动画封装的更多相关文章
- iOS_SN_push/pop转场动画封装和一般动画封装
封装类中的方法: #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface AnimationE ...
- iOS 转场动画探究(一)
什么是转场动画: 转场动画说的直接点就是你常见的界面跳转的时候看到的动画效果,我们比较常见的就是控制器之间的Push和Pop,还有Present和Dismiss的时候设置一下系统给我们的modalTr ...
- iOS 转场动画探究(二)
这篇文章是接着第一篇写的,要是有同行刚看到的话建议从前面第一篇看,这是第一篇的地址:iOS 转场动画探究(一) 接着上一篇写的内容: 上一篇iOS 转场动画探究(一)我们说到了转场要素的第四点,把那个 ...
- iOS转场动画
文顶顶 最怕你一生碌碌无为 还安慰自己平凡可贵 iOS开发UI篇—核心动画(转场动画和组动画) iOS开发UI篇—核心动画(转场动画和组动画) 一.转场动画简单介绍 CAAnimation的子类,用于 ...
- iOS - 转场动画
苹果在 iOS7 定制了 ViewController 的切换效果 一 在iOS5和iOS6之前,ViewController的切换主要有4种 Push/Pop,NavigationViewCotnr ...
- 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 ...
- UIView封装动画--iOS利用系统提供方法来做转场动画
UIView封装动画--iOS利用系统提供方法来做转场动画 UIViewAnimationOptions option; if (isNext) { option=UIViewAnimationOpt ...
随机推荐
- Composer笔记
安装 windows中安装Composer 一般来说,windows下安装composer有两种办法,一种是直接下载并运行Composer-Setup.exe,这种方法在中国似乎很难完成安装.另一种就 ...
- Python 动态导入模块
动态导入模块 目录结构: zhangsandeMacBook-Air:1110 zhangsan$ tree . . ├── lib │ └── aa.py ├── test1.py lib目录下 ...
- linux如何在日志中查找关键字、前几行、结尾几行
如何使用命令行快速查看项目日志是每个开发人员必备技能,尤其在没有专门日志搜集系统的情况下,想要知道目前项目运行状态最好的办法就是打开log日志一瞅即明白. 复杂的到用时再查不晚,但是简单的还是有必要掌 ...
- npm模块管理器入门
什么是 NPM npm 是 Node 官方提供的包管理工具,他已经成了 Node 包的标准发布平台,用于 Node 包的发布.传播.依赖控制.npm 提供了命令行工具,使你可以方便地下载.安装.升级. ...
- c语言的作用域、变量与结构体
一.变量的作用域 根据变量的作用域,可以分为: 1.局部变量: 1> 定义:在函数(代码块)内部定义的变量(包括函数的形参) 2> 作用域:局部变量只有在定义它的函数内部使用,其它函数不能 ...
- 比ngx_http_substitutions_filter_module 更强大的替换模块sregex的replace-filter-nginx-module
之前写过nginx反代替换的教程(传送门),使用了ngx_http_substitutions_filter_module模块.不过这货只能替换同一行,具有局限性-_-# 现在一个更强大的替换模块来了 ...
- Bootstrap 开关(switch)使用整理
1.在JS里根据指定的 1或者0 或者其它值让按钮变成 on 或者 off (通常需要根据数据库查询的结果初始化开关的状态) (--开关插件包 bootstrap-switch.min.js) < ...
- 配置KindEditor富文本编辑器
第一步:首先我们要到KindEditor官网下载资源包-点击进入官网下载KindEditor资源包 第二部:在下载完了KindEditor的资源包后解压结构如下图所示: 里面包括集中语言的文件上传后台 ...
- 当final作用于变量、参数、方法和类时该如何处理
final变量: 对于基本类型使用final:它就是一个常量,数值恒定不变 对于对象引用使用final:使得引用恒定不变,一旦引用被初始化指向一个对象,就无法再把 它改为指向另一个对象.然而,对象自身 ...
- CCF-201509-1-数列分段
问题描述 试题编号: 201509-1 试题名称: 数列分段 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共 ...