自定义segue过渡动画 [英] Custom segue transition animation

查看:83
本文介绍了自定义segue过渡动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用导航控制器的应用程序。我有一个特定的视图控制器,在导航栏中有一个左右按钮,每个按钮都连接到另一个视图控制器。当我按下右键时,我只调用 self.performSegue(withIdentifier: ToDestination,发件人:nil),当我弹出时,调用 _ = self.navigationController?.popViewController(动画:true)

I'm working on an app that utilizes the navigation controller. I have a certain view controller that has a left and right button in the navigation bar and each button segues to a different view controller. When I press the right button, I just call self.performSegue(withIdentifier: "ToDestination", sender: nil) and when I pop back I call _ = self.navigationController?.popViewController(animated: true).

我的问题是按下左按钮时。我可以按下并弹出,但是我希望过渡与右键相反。因为按下了左按钮,所以我希望segue从左向右过渡,当我弹出时,我希望segue从右向左过渡。

My issue is when I press the left button. I can push and pop, but I want the transition to work opposite of the right button. Since I'm pressing the left button, I want the segue to transition from left to right, and when I pop, I want the segue to transition from right to left.

我可以通过以下方式使转换以我想要的方式工作:

I can get the transitions to work the way I want by doing:

//push
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "SearchController") as! SearchController
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 0.5
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
self.navigationController!.view.layer.add(transition, forKey: kCATransition)
self.navigationController!.pushViewController(vc, animated: true)

//pop
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 0.5
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
self.navigationController!.view.layer.add(transition, forKey: kCATransition)
_ = self.navigationController?.popViewController(animated: true)

这可行,但是在视图控制器之间转换时会出现黑色闪烁。有没有更好的方法来获取默认的过渡动画?

This works, but there is a black flash when transitioning between view controllers. Is there a better way to get the default transition animation?

推荐答案

实现方案的最好方法是创建自定义的推入和弹出通过符合 UIViewControllerAnimatedTransitioning 协议进行动画处理:-

The best way to achieve that is to create custom push and pop animation by conforming UIViewControllerAnimatedTransitioning protocol:-

//CustomPushAnimation class

import UIKit

class CustomPushAnimation: NSObject, UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.2
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let containerVw = transitionContext.containerView
        let fromViewController = transitionContext.viewController(forKey: .from)
        let toViewController = transitionContext.viewController(forKey: .to)
        guard let fromVc = fromViewController, let toVc = toViewController else { return }
        let finalFrame = transitionContext.finalFrame(for: toVc)
        //Below line will start from left
        toVc.view.frame = finalFrame.offsetBy(dx: -finalFrame.size.width/2, dy: 0)
        containerVw.addSubview(toVc.view)
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            toVc.view.frame = finalFrame
            fromVc.view.alpha = 0.5
        }, completion: {(finished) in
            transitionContext.completeTransition(finished)
            fromVc.view.alpha = 1.0
        })
    }
}



//CustomPopAnimation class
import UIKit

class CustomPopAnimation: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.2
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let containerView = transitionContext.containerView
        let fromViewController = transitionContext.viewController(forKey: .from)
        let toViewController = transitionContext.viewController(forKey: .to)
        guard let fromVc = fromViewController,
            let toVc = toViewController,
            let snapshotView = fromVc.view.snapshotView(afterScreenUpdates: false)
            else { return }
        let finalFrame = transitionContext.finalFrame(for: fromVc)
        toVc.view.frame = finalFrame
        containerView.addSubview(toVc.view)
        containerView.sendSubview(toBack: toVc.view)
        snapshotView.frame = fromVc.view.frame
        containerView.addSubview(snapshotView)
        fromVc.view.removeFromSuperview()
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            //Below line will start from right
            snapshotView.frame = finalFrame.offsetBy(dx: -finalFrame.size.width, dy: 0)
        }, completion: {(finished) in
            snapshotView.removeFromSuperview()
            transitionContext.completeTransition(finished)
        })
    }
}




最后,您需要显示新的View控制器并设置
动画标记为true,否则将不起作用

And last you need to present the new View controller with setting animation flag to true otherwise it will not work



//Below code should be inside YourViewController
    let vc = UIStoryboard(name: "storyboardName", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerIdentifier")            let navigationController = BaseNavigationController(rootViewController: vc)
    navigationController.transitioningDelegate = self
    present(navigationController, animated: true, completion: nil)




遵循UIViewControllerTransitioningDelegate
协议以制作动画

You also need to conform UIViewControllerTransitioningDelegate protocol in order to work animation



  extension YourViewController: UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            return customPushAnimation
        }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            return customPopAnimation
        }
    }

这篇关于自定义segue过渡动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆