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的操作就是 ...
随机推荐
- Java进阶篇(二)——抽象类、内部类
之前在类和对象中我们说到了类的普通特性,本篇将介绍类的一些高级特性. 一.抽象类 抽象类:抽象类是只声明方法的存在而不去具体实现它的类.抽象类不能被实例化,也就是不能创建其对象.使用abstract关 ...
- [LeetCode] Maximum Length of Pair Chain 链对的最大长度
You are given n pairs of numbers. In every pair, the first number is always smaller than the second ...
- HTTP响应状态解析
100 客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝.客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应.服务器必须在请求完成后向客 ...
- ●POJ 1113 Wall
题链: http://poj.org/problem?id=1113 题解: 计算几何,凸包 题意:修一圈围墙把给出的点包围起来,且被包围的点距离围墙的距离不能小于L,求围墙最短为多少. 答案其实就是 ...
- ●BZOJ 2560 串珠子
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2560 题解: 容斥,状压计数dp 首先求出一个数组 g[s] 表示集合内的点的连边方案数(两 ...
- hdu 2254(矩阵)
题意:指定v1,v2,要求计算出在t1,t2天内从v1->v2的走法 思路:可以知道由矩阵求,即将其建图A,求矩阵A^t1 + ...... + A^t2. A^n后,/*A.xmap[v1 ...
- quartz问题记录-missed their scheduled fire-time
这里有3个原因:1.所有的woker thread(工作线程; 辅助线程)都在运行其他的job2.scheduler(调度器)down了(关于这个down.我不太明确是shutdown了..还是挂掉了 ...
- Android 自定义支持快速搜索筛选的选择控件(一)
Android 自定义支持快速搜索筛选的选择控件 项目中遇到选择控件选项过多,需要快速查找匹配的情况. 做了简单的Demo,效果图如下: 源码地址:https://github.com/whieenz ...
- Linux下如何进入中文目录
给Linux安装图形用户界面之后,会在工作目录中生成图片, 文档, 下载........等中文目录,以前不知道如何进入这些目录,感觉也没有必要,今天在火狐上下载了一个软件,默认在下载这个目录当中,实在 ...
- 《Java技术》第一次作业——Java语言基础
学习总结 Scanner类实现基本数据输入的方法 Scanner 使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹配.然后可以使用不同的 next 方法将得到的标记转换为不同类型的值. ...