之前用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. python-复杂生成式

    1.复杂的列表生成式HTML表格: 注:字符串可以通过%进行格式,用指定的参数化代替%s.字符串的join()方法可以把一list拼接成一个字符串. 把没有几个的分数标记为红色: d = { 'Ada ...

  2. 解决firefox不支持-webkit-line-clamp属性

    转载声明: 请注明本文引用自http://www.cnblogs.com/guolizhi/ css中-webkit-line-clamp这个属性表示超过指定行的文本隐藏并且会在结尾加上...号,用起 ...

  3. codevs 1054 电梯

    1054 电梯 提交地址:http://codevs.cn/problem/1054/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver     题目描述 D ...

  4. [SHOI2016]黑暗前的幻想乡

    Description 四年一度的幻想乡大选开始了,最近幻想乡最大的问题是很多来历不明的妖 怪涌入了幻想乡,扰乱了幻想乡昔日的秩序.但是幻想乡的建制派妖怪(人类) 博丽灵梦和八云紫等人整日高谈所有妖怪 ...

  5. 【BZOJ3531】【SDOI2014】旅行

    题目传送门 题目大意:给定一棵无根树,每个节点有自己的类别和权值,现在给定两个类别相同的点,叫你求这2点路径上同类别节点的权值和/最大权值. 节点类别与权值会改变. 解题思路:考虑对每一个类别开一棵线 ...

  6. HDU 4641 K-string

    Description Given a string S. K-string is the sub-string of S and it appear in the S at least K time ...

  7. 习题9-5 UVA 242

    Stamps and Enovelope Size 题意: 给你最多贴S张邮票.有N个邮票集合,每个集合有不同的面值.问哪个集合的最大连续邮资最大,输出最大连续邮资和集合元素. 如果不止一个集合结果相 ...

  8. hdu 1133 Buy the Ticket(Catalan)

    Buy the Ticket Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  9. hdu 1130 How Many Trees?(Catalan数)

    How Many Trees? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  10. VB.NET 泛型类型的应用经验

    VB.NET编程语言中的数据类型种类繁多,初学者要想全部掌握这些类型的应用是一个比较困难的步骤.今天我们先让大家了解一下VB.NET泛型类型这一高阶技术的应用,以便让大家对这一语言进行深入的解读. 定 ...