美文网首页
转场动画(一)--自定义转场动画

转场动画(一)--自定义转场动画

作者: Theshy | 来源:发表于2016-06-16 18:57 被阅读348次
    一 设置控制器代理 transitioningDelegate
        pictureVC.transitioningDelegate = self
    
    二 设置转场模式 modalPresentationStyle
        pictureVC.modalPresentationStyle = UIModalPresentationStyle.Custom
    
    • 默认的转场 系统present之后 底层的view被移除出控制器

    • 自定义转场 底层的view依旧在 新的视图只是遮盖在上面

    三 遵守协议 UIViewControllerTransitioningDelegate
    • 实现代理方法
        extension HomeTableViewController: UIViewControllerTransitioningDelegate {
        /**
           返回提供转场动画的对象   这个对象可以是任何一个对象 只要遵守了 UIViewControllerAnimatedTransitioning 协议
         */
          func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            return self
          }
        
        /**
         返回提供解除动画的对象
         */
        
          func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            return self
          }
        }
    
    • 此时两个方法会报错 因为 return self 没有遵守协议UIViewControllerAnimatedTransitioning 在写一个类扩展遵守协议
      extension HomeTableViewController: UIViewControllerAnimatedTransitioning {
        
      }
    
    • 此时错误会转移到下边的类扩展 因为没有实现协议方法 协议方法中有两个必须一个可选
    extension HomeTableViewController: UIViewControllerAnimatedTransitioning {
        
        // 转场动画时长
        func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
            return 2.0
        }
        
        /**
         自定义转场动画
         
         - parameter transitionContext: 提供了转场动画所需要的元素
         */
        func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
            
            // 此方法必须实现(API 注明)
            transitionContext.completeTransition(true)
        }
    }
    
    
    • 此时运行代码 发现不会弹出控制器了 因为只要实现了此方法 就需要自己写动画
      func animateTransition(transitionContext: UIViewControllerContextTransitioning)

    • 此时需要先把 上边的 返回解除转场动画的方法注释掉
      func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?

    
    extension HomeTableViewController: UIViewControllerAnimatedTransitioning {
        
        // 转场动画时长
        func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
            return 2.0
        }
        
        /**
         自定义转场动画  只要实现了此方法 就需要自己写动画
         
         - parameter transitionContext: 提供了转场动画所需要的元素
         - transitionContext.completeTransition(true) 动画结束后必须调用
         
         - containerView() 容器视图
         
         - viewForKey      获取到转场的视图  ios8.0
         */
        func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
            
            // MainViewController 弹出视图的控制器
            let fromVc = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
            // 要展现的控制器
            let toVc = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
            
            let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
            transitionContext.containerView()?.addSubview(toView)
            
            toView.alpha = 0.0
            
            UIView.animateWithDuration(transitionDuration(transitionContext), animations: { 
                toView.alpha = 1.0
                }) { (_) in
                    
                    // 此方法必须实现(API 注明)  
                    // 动画结束之后一定要执行,如果不执行,系统会一直等待,无法进行后续交互
                    
                    transitionContext.completeTransition(true)
            }
        }
    }
    
    • 此时已经能够实现转场动画了 接下来解决解除转场, 不然关闭的时候 直接下去没有别的动画

    • 打开刚刚注释掉的方法
      定义属性记录 是否已经转场 不然拿到的toView会有问题

        // 是否转场
        private var isPresent : Bool = true
    
    
    extension HomeTableViewController: UIViewControllerTransitioningDelegate {
        
        /**
         返回提供转场动画的对象   这个对象可以是任何一个对象 只要遵守了 UIViewControllerAnimatedTransitioning 协议
         */
        func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            
            isPresent = true
            
            return self
        }
        
        /**
         返回提供解除动画的对象
         */
        
        func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            
            isPresent = false
            
            return self
        }
        
    }
    
    extension HomeTableViewController: UIViewControllerAnimatedTransitioning {
        
        // 转场动画时长
        func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
            return 2.0
        }
        
        /**
         自定义转场动画  只要实现了此方法 就需要自己写动画
         
         - parameter transitionContext: 提供了转场动画所需要的元素
         - transitionContext.completeTransition(true) 动画结束后必须调用
         
         - containerView() 容器视图
         
         - viewForKey      获取到转场的视图  ios8.0
         */
        func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
            
            // MainViewController 弹出视图的控制器
    //        let fromVc = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
            // 要展现的控制器
    //        let toVc = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
            
            
            if isPresent {
                let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
                transitionContext.containerView()?.addSubview(toView)
                
                toView.alpha = 0.0
                
                UIView.animateWithDuration(transitionDuration(transitionContext), animations: {
                    toView.alpha = 1.0
                }) { (_) in
                    
                    // 此方法必须实现(API 注明)
                    // 动画结束之后一定要执行,如果不执行,系统会一直等待,无法进行后续交互
                    
                    transitionContext.completeTransition(true)
                }
    
            } else {
                // 解除转场的时候 fromVc 是 present出来的控制器  反了一下
                let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
                UIView.animateWithDuration(transitionDuration(transitionContext), animations: { 
                    fromView.alpha = 0.0
                    }, completion: { (_) in
                        
                        fromView.removeFromSuperview()
                        // 解除转场 会把容器视图和内部视图 销毁
                        transitionContext.completeTransition(true)
                })
    
            }
    
        }
    }
    
    

    相关文章

      网友评论

          本文标题:转场动画(一)--自定义转场动画

          本文链接:https://www.haomeiwen.com/subject/invmdttx.html