之前用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. Unity中的基础光照

    渲染包含了两大部分:决定一个像素的可见性,决定这个像素上的光照计算. 光照模型就是用于决定在一个像素上进行怎样的光照计算. 一.光源 在实时渲染中我们通常把光源当做一个没有体积的点. 1.1 辐照度 ...

  2. Docker配置加速器

    我们国内使用官方Docker Hub仓库实在是太慢了,很影响效率 使用命令编辑文件: vim /etc/docker/daemon.json 加入下面的数据: docker-cn镜像: { " ...

  3. DDD实战进阶第一波(五):开发一般业务的大健康行业直销系统(实现产品上下文领域层)

    从这篇文章开始,我们根据前面的DDD理论与DDD框架的约束,正式进入直销系统案例的开发. 本篇文章主要讲产品上下文中的领域层的主要实现,先简单讲下业务方面的需求:产品SPU与产品SKU,产品SPU主要 ...

  4. dropzone.js使用实践

    官网地址:http://www.dropzonejs.com/ 一,它是什么: DropzoneJS is an open source library that provides drag'n'dr ...

  5. Struts2--struts.xml详解

    通常,struts.xml文件都会继承一个struts-default.xml文件通过一些基本的拦截器来提供一些基本的配置设置之类的. 配置例: <?xml version="1.0& ...

  6. [SDOI 2010]魔法猪学院

    Description 题库链接 给出一张 \(n\) 个点 \(m\) 条边有向图,询问最多有多少条不同的路径从 \(1\) 到 \(n\) 并且路径长度和 \(\leq E\) . \(2\leq ...

  7. [HNOI 2015]菜肴制作

    Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1到N的顺序编号,预估质量最高的菜肴编号 ...

  8. LGTB 与序列

    LGTB 有一个长度为N 的序列A,现在他想构造一个新的长度为N 的序列B,使得B 中的任意两个数都 互质. 并且他要使ai与bi对应项之差最小 请输出最小值 输入 第一行包含一个数N 代表序列初始长 ...

  9. 【BZOJ2705】【Sdoi2012】Longge的问题

    Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出\(\Sigma gcd(i, N) (1 \leq i \leq N ...

  10. ●BZOJ 4566 [Haoi2016]找相同字符

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4566题解: 广义后缀自动机 对两个串同时建立一个广义后缀自动机. 同时统计出每个状态对两个串 ...