不使用Storyboard segues的自定义视图转换(Swift)

时间:2015-07-27 00:02:36

标签: ios swift presentviewcontroller custom-transition

我有两个观点我希望进行滑动式转换,我已经完成了当有一个segue进行操作但我没有在这里,所以我不知道如何应用我的动画类。我班上的所有内容都是:

let stb = UIStoryboard(name: "Walkthrough", bundle: nil)
    let walkthrough = stb.instantiateViewControllerWithIdentifier("walk") as! BWWalkthroughViewController

self.presentViewController(walkthrough, animated: true, completion: nil)

我想申请应用以下自定义segue:

class CustomSegue: UIStoryboardSegue {

  override func perform() {
    // Assign the source and destination views to local variables.
    var firstVCView = self.sourceViewController.view as UIView!
    var secondVCView = self.destinationViewController.view as UIView!

    // Get the screen width and height.
    let screenWidth = UIScreen.mainScreen().bounds.size.width
    let screenHeight = UIScreen.mainScreen().bounds.size.height

    // Specify the initial position of the destination view.
    secondVCView.frame = CGRectMake(0.0, screenHeight, screenWidth, screenHeight)

    // Access the app's key window and insert the destination view above the current (source) one.
    let window = UIApplication.sharedApplication().keyWindow
    window?.insertSubview(secondVCView, aboveSubview: firstVCView)

    // Animate the transition.
    UIView.animateWithDuration(0.2, animations: { () -> Void in
      firstVCView.frame = CGRectOffset(firstVCView.frame, -screenWidth, 0.0)
      secondVCView.frame = CGRectOffset(secondVCView.frame, -screenWidth, 0.0)

      }) { (Finished) -> Void in

      self.sourceViewController.presentViewController(self.destinationViewController as! UIViewController,
          animated: false,
          completion:nil)
    }
  }
}

我不能让它工作任何指针吗?

1 个答案:

答案 0 :(得分:5)

虽然第一个答案应该是“使用Storyboard Segues”,但您可以通过以下方式解决自定义转换:

通用方法

  1. 修改您的CustomSegue以采用 <{strong> UIStoryboardSegue UIViewControllerAnimatedTransitioning协议。
  2. 重构CustomSegue,以便两个协议都可以使用动画。
  3. delegate设置到导航控制器,导航控制器本身就可以将自定义转换提供给push&amp; pop
  4. animationControllerForOperation创建并返回CustomSegue的实例,并带有您选择的标识符。
  5. <强>概述

    // Adopt both protocols
    class CustomSegue: UIStoryboardSegue, UIViewControllerAnimatedTransitioning {
    
        func animate(firstVCView:UIView,
            secondVCView:UIView,
            containerView:UIView,
            transitionContext: UIViewControllerContextTransitioning?) {
                // factored transition code goes here
                    }) { (Finished) -> Void in
                        if let context = transitionContext {
                            // UIViewControllerAnimatedTransitioning
                        } else {
                            // UIStoryboardSegue
                        }
                }
        }
    
        func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
            // return timing
        }
    
        func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
            // Perform animate using transitionContext information
            // (UIViewControllerAnimatedTransitioning)
        }
    
        override func perform() {
            // Perform animate using segue (self) variables
            // (UIStoryboardSegue) 
        }
    }
    

    以下是完整代码示例。它已经过测试。请注意,我还修复了原始问题中的一些动画错误,并添加了淡入效果以强调动画。

    CustomSegue类

    // Animation for both a Segue and a Transition
    class CustomSegue: UIStoryboardSegue, UIViewControllerAnimatedTransitioning {
    
        func animate(firstVCView:UIView,
            secondVCView:UIView,
            containerView:UIView,
            transitionContext: UIViewControllerContextTransitioning?) {
    
                // Get the screen width and height.
                let offset = secondVCView.bounds.width
    
                // Specify the initial position of the destination view.
                secondVCView.frame = CGRectOffset(secondVCView.frame, offset, 0.0)
    
                firstVCView.superview!.addSubview(secondVCView)
                secondVCView.alpha = 0;
    
                // Animate the transition.
                UIView.animateWithDuration(self.transitionDuration(transitionContext!),
                    animations: { () -> Void in
                        firstVCView.frame = CGRectOffset(firstVCView.frame, -offset, 0.0)
                        secondVCView.frame = CGRectOffset(secondVCView.frame, -offset, 0.0)
                        secondVCView.alpha = 1; // emphasis
    
                    }) { (Finished) -> Void in
                        if let context = transitionContext {
                            context.completeTransition(!context.transitionWasCancelled())
                        } else {
                            self.sourceViewController.presentViewController(
                                self.destinationViewController as! UIViewController,
                                animated: false,
                                completion:nil)
                        }
                }
        }
    
        func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
            return 4 // four seconds
        }
    
        // Perform Transition (UIViewControllerAnimatedTransitioning)
        func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
            self.animate(transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!.view,
                secondVCView: transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!.view,
                containerView: transitionContext.containerView(),
                transitionContext: transitionContext)
        }
    
        // Perform Segue (UIStoryboardSegue)
        override func perform() {
            self.animate(self.sourceViewController.view!!,
                secondVCView: self.destinationViewController.view!!,
                containerView: self.sourceViewController.view!!.superview!,
                transitionContext:nil)
        }
    }
    

    主机ViewController类

    class ViewController: UIViewController, UINavigationControllerDelegate {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.navigationController?.delegate = self
        }
    
        func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            switch operation {
            case .Push:
                 return CustomSegue(identifier: "Abc", source: fromVC, destination: toVC)
    
            default:
                return nil
            }
        }
    }