2017-07-29 86 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 
     } 
    }