2017-07-29 65 views
2

我正在使用导航控制器的应用程序。我有一个特定的视图控制器,在导航栏中有一个左右按钮,每个按钮都延伸到不同的视图控制器。当我按下右键时,我只需拨打self.performSegue(withIdentifier: "ToDestination", sender: nil),当我回电时,我拨打_ = self.navigationController?.popViewController(animated: true)自定义segue过渡动画

我的问题是当我按下左按钮。我可以推动和弹出,但我希望过渡与右侧按钮相反。由于我按了左键,我想让segue从左到右转换,当我弹出时,我希望segue从右向左转换。

我能得到的转换通过做工作,我想要的方式:

//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) 

这工作,但视图控制器之间转换时黑色闪光。有没有更好的方式来获得默认的过渡动画?

回答

2

实现,最好的办法是由符合UIViewControllerAnimatedTransitioning协议创建自定义push和pop动画: -

//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) 
     }) 
    } 
} 

和最后你需要 动画标志设置为true,出现新的视图控制器否则将无法正常工作

//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 协议,以工作动画

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

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