之前用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跳转动画的更多相关文章

  1. UINavigationController导航控制器初始化 导航控制器栈的push和pop跳转理解

    (1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最下面,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...

  2. iOS开发-21UINavigationController导航控制器初始化 导航控制器栈的push和pop跳转理解

    (1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最下面,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...

  3. 【iOS开发-21】UINavigationController导航控制器初始化,导航控制器栈的push和pop跳转理解

    (1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最以下,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...

  4. 更改navigationController push和pop界面切换动画

    For Push: MainView *nextView=[[MainView alloc] init]; [UIView beginAnimations:nil context:NULL]; [UI ...

  5. 自定义UINavigationController push和pop动画

    http://segmentfault.com/q/1010000000143983 默认的UINavigationController push和pop的默认动画都是左右滑动推出,我的应用要求这种界 ...

  6. 自定义Push/Pop和Present/Dismiss转场

    项目概述 iOS中最常见的动画无疑是Push和Pop的转场动画了,其次是Present和Dismiss的转场动画. 如果我们想自定义这些转场动画,苹果其实提供了相关的API,在自定义转场之前,我们需要 ...

  7. iOS如何随意的穿插跳跃,push来pop去

    iOS如何随意的穿插跳跃,push来pop去? 主题思想:如A.B.C.D 四个视图控制器. 想要在 A push B 后, B 在push 到 D ,然后从 D pop 到 C ,在从 C pop ...

  8. iOS 如何随意的穿插跳跃,push来pop去

    OS 如何随意的穿插跳跃,push来pop去 主题思想:如A.B.C.D 四个视图控制器 想要在 A push B 后, B 在push 到 D ,然后从 D pop 到 C ,在从 C pop 的A ...

  9. MongoDB之$关键字及$修改器$set $inc $push $pull $pop

    一.查询中常见的  等于   大于  小于  大于等于  小于等于 等于:用':' 大于:用'$gt' 小于:用'$lt' 大于等于:用'$gte' 小于等于:用'$lte' MongoDB的操作就是 ...

随机推荐

  1. pyquery 的用法 --爬虫解析库

    如果你对Web有所涉及,如果你比较喜欢用CSS选择器,如果你对jQuery有所了解,那么这里有一个更适合你的解析库--pyquery. 接下来,我们就来感受一下pyquery的强大之处. 1. 准备工 ...

  2. 基于线程池的多线程售票demo2.0(原创)

    继上回基于线程池的多线程售票demo,具体链接: http://www.cnblogs.com/xifenglou/p/8807323.html以上算是单机版的实现,特别使用了redis 实现分布式锁 ...

  3. 微信小程序之Todo

    wxAppTodos   todomvc提供了在当今大多数流行的JavaScript MV*框架概念实现的相同的Todo应用程序,觉得这个小项目挺有意思,最近在学习微信小程序,故用小程序做一版Todo ...

  4. [python]使用django快速生成自己的博客小站,含详细部署方法

    前言 人生苦短,我用python 这是之前经常听到的一句笑谈.因为新公司很多业务是用的python语言,所以这几天也一直在学习python的一些东西. 作为一个之前一直java后端的开发人员,对比ja ...

  5. vba打开输入文件

    Sub fileCreate2() Dim folderPath, fileName, s As String Dim fs, fo, fc, f As Object folderPath = &qu ...

  6. [SCOI 2016]美味

    Description 题库链接 给你一个长度为 \(n\) 的序列 \(A\) . \(m\) 组询问 \((b,x,l,r)\) 询问 \[\max_{i=l}^r b\oplus (A_i+x) ...

  7. NOIP 2011 观光公交

    题目描述 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第 0 分钟出现在 1号景点,随后依次前往 2 ...

  8. hdu 5119(2014北京)

    题意: 随机选择一个数,如果后面有比他小的就进行交换,直到没有为止(算一轮).求多少轮后为递增序列 思路: 倒着找,如果有比经过的最小数大的,ans+1 #include <iostream&g ...

  9. hdu2795 线段树 贴广告

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  10. Python3 运算符

    装载自:https://www.cnblogs.com/cisum/p/8064222.html Python3 运算符 什么是运算符? 本章节主要说明Python的运算符.举个简单的例子 4 +5 ...