美文网首页
自定义转场动画入门

自定义转场动画入门

作者: 纳兰沫 | 来源:发表于2019-11-18 13:51 被阅读0次

新建UIViewControllerAnimatedTransitioning的子类 由于要实现NSObjectProtocol 所以要继承NSObject

转场动画分为非交互性转场动画 和 交互性转场动画(手势)

只有在交互动画里面才有取消动画一说 !transitionContext.transitionWasCancelled 根据动画是否取消判断动画是否结束

let detailVC = storyboard?.instantiateViewController(withIdentifier: "DetailVc") as! ViewController
        
detailVC.transitioningDelegate = self
        
present(detailVC, animated: true, completion: nil)
extension MainViewController: UIViewControllerTransitioningDelegate {
    
    //自定义动画
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return PresentAnimation()
    }
    
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return DismissAnimation()
    }
    
}
class PresentAnimation: NSObject,UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        
        guard let fromVC = transitionContext.viewController(forKey: .from),
        let toVC = transitionContext.viewController(forKey: .to),
        let fromView = transitionContext.view(forKey: .from),
        let toView = transitionContext.view(forKey: .to) else{ return }
        
        let containerView = transitionContext.containerView
        
        containerView.addSubview(toView)
        
        //自定义动画
        toView.alpha = 0
        toView.transform = CGAffineTransform(translationX: containerView.frame.width, y: 0)
        UIView.animate(
            withDuration: transitionDuration(using: transitionContext),
            animations: {
                fromView.alpha = 0
                fromView.transform = CGAffineTransform(translationX: -containerView.frame.width, y: 0)
                toView.alpha = 1
                toView.transform = .identity
        }) { _ in
            
            fromView.transform = .identity
            toView.transform = .identity
            transitionContext.completeTransition(true)
        }
    }
    

}
class DismissAnimation: NSObject,UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        
        let containerView = transitionContext.containerView
        guard let fromVC = transitionContext.viewController(forKey: .from),
            let toVC = transitionContext.viewController(forKey: .to),
            let fromView = transitionContext.view(forKey: .from),
            let toView = transitionContext.view(forKey: .to) else{ return }
        
        containerView.addSubview(toView)
        
        toView.alpha = 0
//        toView.transform = CGAffineTransform(translationX: -containerView.frame.width, y: 0)
        
        UIView.animate(
            withDuration: transitionDuration(using: transitionContext),
            animations: {
                
                toView.alpha = 1
                toView.transform = .identity
                fromView.alpha = 0
                fromView.transform = CGAffineTransform(translationX: containerView.frame.width, y: 0)
        }) { _ in
            //fromView虽然被自动从containerView 里面移除了 但附在身上的transform属性还在 为了防止再次动画交错 要置空
            fromView.transform = .identity
            //虽然toViewdtransform在动画块里面置空了 但如果交互动画时用户取消转场了 就会被附上初始时定的transform 所以 为了不干扰下一次动画 这里也要置空
            toView.transform = .identity
            transitionContext.completeTransition(true)
        }
    }
    

}

相关文章

网友评论

      本文标题:自定义转场动画入门

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