Swift基础之自定义PUSH和POP跳转动画
之前用OC代码写过PUSH和POP的转场动画,闲来无事,将其转换成Swift语言,希望对大家有帮助,转载请注明。。。。
如何实现PUSH和POP的转场动画?
首先,创建一个NSObject的类,分别用来实现PUSH和POP的动画效果
创建PUSH文件,实现扇形效果,代码如下:
需要注意的是,代理的实现方法要完整
var transitionContextT:UIViewControllerContextTransitioning?
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.8
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
self.transitionContextT = transitionContext
let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
//不添加的话,屏幕什么都没有
let containerView = transitionContext.containerView
containerView.addSubview((fromVC?.view)!)
containerView.addSubview((toVC?.view)!)
let originRect:CGRect = CGRect.init(x: 0, y: 0, width: 50, height: 50)
let maskStartPath = UIBezierPath.init(ovalIn: originRect)
//OC中CGRectInset(originRect, -2000, -2000)的Swift用法:originRect.insetBy(dx: -2000, dy: -2000)
let maskEndPath = UIBezierPath.init(ovalIn: originRect.insetBy(dx: -2000, dy: -2000))
//创建一个CAShapeLayer来负责展示圆形遮盖
let maskLayer = CAShapeLayer.init()
//将他的path指定为最终的path,来避免在动画完成后回弹
maskLayer.path = maskEndPath.cgPath
toVC?.view.layer.mask = maskLayer
let maskAnimation = CABasicAnimation.init(keyPath: "path")
maskAnimation.fromValue = maskStartPath.cgPath
maskAnimation.toValue = maskEndPath.cgPath
maskAnimation.duration = self.transitionDuration(using: transitionContext)
maskAnimation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
maskAnimation.fillMode = kCAFillModeForwards
maskAnimation.isRemovedOnCompletion = false
maskAnimation.delegate = self
maskLayer.add(maskAnimation, forKey: "path")
}
//MARK:----- CAAnimationDelegate
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
self.transitionContextT?.completeTransition(!(self.transitionContextT?.transitionWasCancelled)!)
//去除mask
self.transitionContextT?.viewController(forKey: UITransitionContextViewControllerKey.from)?.view.layer.mask = nil;
self.transitionContextT?.viewController(forKey: UITransitionContextViewControllerKey.to)?.view.layer.mask = nil;
}
然后,同理创建POP文件,实现弹跳的效果,代码如下:
var transitionContext:UIViewControllerContextTransitioning?
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.8
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
self.transitionContext = transitionContext
let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
//不添加的话,屏幕什么都没有
let containerView = transitionContext.containerView
containerView.addSubview((fromVC?.view)!)
containerView.addSubview((toVC?.view)!)
let durationN = self.transitionDuration(using: transitionContext)
let screenBounds:CGRect = UIScreen.main.bounds
let finalFrame:CGRect = transitionContext.finalFrame(for: toVC!)
//OC中CGRectOffset(finalFrame, 0, -screenBounds.size.height)的Swift的用法:finalFrame.offsetBy(dx: 0, dy: -screenBounds.size.height)
toVC?.view.frame = finalFrame.offsetBy(dx: 0, dy: -screenBounds.size.height)
//添加动画,有弹跳的效果,参数:usingSpringWithDamping的范围为0.0f到1.0f,数值越小「弹簧」的振动效果越明显,当设置为1.0时,就不弹跳
//toVC?.view.frame = finalFrame
//transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
UIView.animate(withDuration: durationN, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.0, options: UIViewAnimationOptions.curveLinear, animations: {() -> Void in
//print("11111111")
toVC?.view.frame = finalFrame
}, completion: ({(Bool) -> Void in
//print("22222222")
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}))
}
最后在需要使用跳转动画的地方添加self.navigationController?.delegate = self代理方法,并实现,代码如下:
//MARK:-----UINavigationControllerDelegate
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if operation==UINavigationControllerOperation.push {
return BHPopAnimation()
}
else if operation==UINavigationControllerOperation.pop{
return BHPushAnimation()
}
return nil
}
最后附上源代码,如果有问题请留言:https://github.com/hbblzjy/SwiftPushAndPopDemo
Swift基础之自定义PUSH和POP跳转动画的更多相关文章
- UINavigationController导航控制器初始化 导航控制器栈的push和pop跳转理解
(1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最下面,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...
- iOS开发-21UINavigationController导航控制器初始化 导航控制器栈的push和pop跳转理解
(1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最下面,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...
- 【iOS开发-21】UINavigationController导航控制器初始化,导航控制器栈的push和pop跳转理解
(1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最以下,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...
- 更改navigationController push和pop界面切换动画
For Push: MainView *nextView=[[MainView alloc] init]; [UIView beginAnimations:nil context:NULL]; [UI ...
- 自定义UINavigationController push和pop动画
http://segmentfault.com/q/1010000000143983 默认的UINavigationController push和pop的默认动画都是左右滑动推出,我的应用要求这种界 ...
- 自定义Push/Pop和Present/Dismiss转场
项目概述 iOS中最常见的动画无疑是Push和Pop的转场动画了,其次是Present和Dismiss的转场动画. 如果我们想自定义这些转场动画,苹果其实提供了相关的API,在自定义转场之前,我们需要 ...
- iOS如何随意的穿插跳跃,push来pop去
iOS如何随意的穿插跳跃,push来pop去? 主题思想:如A.B.C.D 四个视图控制器. 想要在 A push B 后, B 在push 到 D ,然后从 D pop 到 C ,在从 C pop ...
- iOS 如何随意的穿插跳跃,push来pop去
OS 如何随意的穿插跳跃,push来pop去 主题思想:如A.B.C.D 四个视图控制器 想要在 A push B 后, B 在push 到 D ,然后从 D pop 到 C ,在从 C pop 的A ...
- MongoDB之$关键字及$修改器$set $inc $push $pull $pop
一.查询中常见的 等于 大于 小于 大于等于 小于等于 等于:用':' 大于:用'$gt' 小于:用'$lt' 大于等于:用'$gte' 小于等于:用'$lte' MongoDB的操作就是 ...
随机推荐
- mysql zip 文件安装
1.下载 https://dev.mysql.com/downloads/mysql/ 2.解压,配置环境变量 MYSQL_HOME:D:\mysql path后面加 :%MYSQL_HOME%\bi ...
- [LeetCode] Range Addition II 范围相加之二
Given an m * n matrix M initialized with all 0's and several update operations. Operations are repre ...
- 【linux之压缩归档,tar】
一.压缩和归档 压缩算法就是等量代换 gzip FILE1 FILE2... 扩展名 .gz -#(数字):#代表压缩等级,1-9,默认6 -d(compression):解压缩 -r:递归的压缩目录 ...
- angularjs中使用 <input type="file">标签实现一次最多上传5张图片
前期准备: 1.angular.js 2.bootstrap.css 具体如何实现呢?请看下面代码哈哈哈. 在angular项目中,如果要给<input type="file" ...
- MQTT客户端库-Paho GO
为了加深理解,本文是翻译文章.原文地址 Paho GO Client 语言 GO 协议 EPL AND EDL 官网地址 http://www.eclipse.org/paho/ API类型 As ...
- ●BZOJ 3512 DZY Loves Math IV
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3512 题解: $$求ANS=\sum_{i=1}^{N}\sum_{j=1}^{M}\phi ...
- 【luogu3384】【模板】树链剖分
省选被暴虐,成功爆0...顺便ditoly差点全省总分Rank1 orz..... 于是开始赶进度学新算法.... 然后决定开始学习树剖orz... 发现树剖很好用啊!!!! 然后做了模板题. 题目就 ...
- [洛谷]P3613 睡觉困难综合征
题目大意:给出一棵n个点的树,每个点有一个运算符(与.或.异或)和一个数,支持两种操作,第一种修改一个点的运算符和数,第二种给出x,y,z,询问若有一个0~z之间的数从点x走到点y(简单路径),并且对 ...
- 【USACO17JAN】Promotion Counting晋升者计数 线段树+离散化
题目描述 The cows have once again tried to form a startup company, failing to remember from past experie ...
- 《Java技术》第一次作业
(一)学习总结 1.在java中通过Scanner类完成控制台的输入,查阅JDK帮助文档,Scanner类实现基本数据输入的方法是什么?不能只用文字描述,一定要写代码,通过具体实例加以说明. (1)使 ...