2015-07-27 18 views
5

Ho due visualizzazioni Vorrei passare attraverso una transizione di stile e l'ho fatto quando c'è un seguito su cui agire ma non ne ho uno qui quindi non sono sicuro di come applicare la mia lezione di animazione. Tutto quello che ho nella mia classe è:Transizione vista personalizzata senza utilizzo di storyboard segues (Swift)

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

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

voglio applicare applicare il seguente segue personalizzato:

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

non riesco a farlo funzionare tutti i puntatori per favore?

+0

Si noti che non è necessario usare 'UIScreen.mainScreen()' e che si può effettivamente creare una certa confusione. Si noti inoltre che se si rallenta l'animazione a 4 secondi, sembra che vengano svelati artefatti indesiderati. – SwiftArchitect

risposta

5

Mentre la prima risposta dovrebbe essere "utilizzare Storyboard Segues", è possibile risolvere le transizioni personalizzati in questo modo:

approccio generico

  1. Modificare la tua CustomSegue di adottare siaUIStoryboardSeguee Protocolli UIViewControllerAnimatedTransitioning.
  2. Refactor CustomSegue in modo che l'animazione possa essere utilizzata da entrambi i protocolli.
  3. Setup un delegate per il controller di navigazione, che può essere per sé, a fornire le transizioni personalizzate per push & pop
  4. lasciare animationControllerForOperation creare e restituire un'istanza di CustomSegue, con un identificatore di vostra scelta.

Panoramica

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

Di seguito si riporta l'esempio di codice completo . È stato testato Notare che ho anche risolto alcuni bug di animazione dalla domanda originale e aggiunto un effetto di dissolvenza per enfatizzare l'animazione.


CustomSegue Classe

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

Host ViewController Classe

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 
     } 
    } 
} 
+0

Grazie, non riesco a vedere come applicarlo al mio codice? – SashaZ

+0

Ben fatto Lancelot. – BonanzaDriver

+0

Brillante Voglio a casa applicarlo. Andrò stasera dopo il lavoro, incredibile! – SashaZ

Problemi correlati