ios - protocol - swift viewcontroller delegate




Modo corretto per implementare una transizione interattiva personalizzata UIViewController utilizzando UIViewControllerInteractiveTransitioning Delegate Protocol (2)

Mi interessa un breve esempio di come creare una sottoclasse NSObject che implementa il protocollo UIViewControllerInteractiveTransitioning per gestire una transizione interattiva personalizzata tra due UIViewController . Idealmente in risposta a un gesto di sfioramento. Qualcosa di simile allo swipe interattivo predefinito di iOS7 che ora viene fornito con UINavigationController , ma un esempio di implementazione personalizzata / manuale di questo.

Ho letto i documenti:

E ho visto alcuni esempi altrove:

  • one
  • two
  • three
  • four (l'ho impostato ma è più relativo UIViewController containment UIViewController e all'implementazione manuale di queste transizioni piuttosto che a UIViewControllerInteractiveTransitioning

I documenti sono abbastanza chiari ma non si fa riferimento al codice di esempio. E gli esempi lasciano un po 'a desiderare (domande senza risposta su come i vari pezzi sono legati insieme).

Quindi le mie domande sono:

  1. Qualcuno può aiutare a riempire gli spazi vuoti su come legare un gesto (ad esempio uno swipe) all'oggetto che implementa il protocollo UIViewControllerInteractiveTransitioning ?
  2. Qual è la relazione tra l'oggetto che implementa il protocollo UIViewControllerInteractiveTransitioning e quello che implementa il protocollo UIViewControllerAnimatedTransitioning? Sembra che tu debba avere entrambi per attivare transizioni interattive ...

Grazie in anticipo...


Apple fornisce ora un progetto di esempio per come è possibile ottenere questo risultato. Detto questo, non penso sia l'esempio migliore / più chiaro, ma dovrebbe portarti sulla strada giusta.

Hanno anche un video WWDC che ti porta attraverso questo stesso progetto.

Sappi che è un esempio abbastanza complesso, ma se riesci a separarlo e capire i vari pezzi, dovresti essere equipaggiato per affrontare più o meno qualsiasi cosa sul fronte della transizione.

Essenzialmente, il progetto suddivide il problema in due classi helper, 1) un AssetTransitionController che è inizializzato con, ed esiste per la durata di, il controller della vista, e 2) un oggetto AssetTransitionDriver creato all'inizio ed esistente per durata di, una transizione.

AssetTransitionController è abbastanza semplice, è conforme a UIViewControllerAnimatedTransitioning e UIViewControllerInteractiveTransitioning gestisce il ciclo di vita di AssetTransitionDriver .

AssetTransitionDriver è una sottoclasse NSObject semplice ma in realtà finisce molto più complessa. Gestisce l' UIViewPropertyAnimator principale, creando la gerarchia delle viste per la transizione e risponde al driver di interazione (un riconoscitore di gesture pan). Quando richiesto, vende anche il suo animatore ad AssetTransitionController .

Non usa affatto UIPercentDrivenInteractiveTransition .


1) Il modo più semplice per legare un gesto all'oggetto UIViewControllerInteractiveTransitioning è renderlo sottoclasse di UIPercentDrivenInteractiveTransition . Quindi, quando implementi il ​​gestore di gesti, chiami updateInteractiveTransition: qui un esempio con codice:

-(void)handlePinch:(UIPinchGestureRecognizer *)pinch {

    CGFloat scale = pinch.scale;
    switch (pinch.state) {
      case UIGestureRecognizerStateBegan: {
          _startScale = scale;
          self.interactive = YES;
          [self.navigationController popViewControllerAnimated:YES];
          break;
      }
      case UIGestureRecognizerStateChanged: {
          CGFloat percent = (1.0 - scale/_startScale);
          [self updateInteractiveTransition:(percent < 0.0) ? 0.0 : percent];
          break;
      }
      case UIGestureRecognizerStateEnded: {
          CGFloat percent = (1.0 - scale/_startScale);
          BOOL cancelled = ([pinch velocity] < 5.0 && percent <= 0.3);
          if (cancelled) [self cancelInteractiveTransition];
          else [self finishInteractiveTransition];
          break;
      }
      case UIGestureRecognizerStateCancelled: {
          CGFloat percent = (1.0 - scale/_startScale);
          BOOL cancelled = ([pinch velocity] < 5.0 && percent <= 0.3);
          if (cancelled) [self cancelInteractiveTransition];
          else [self finishInteractiveTransition];
          break;
      }
    }
}

Questo codice proviene da https://www.captechconsulting.com/blogs/ios-7-tutorial-series-custom-navigation-transitions--more

2) La funzione animateTransition di UIViewControllerAnimatedTransitioning viene utilizzata per eseguire la transizione interattiva. Viene partizionato automaticamente in "fotogrammi chiave" grazie alla precedente chiamata a updateInteractiveTransition . Ma suppongo che se implementi il ​​tuo startInteractiveTransition: metodo di UIViewControllerInteractiveTransitioning (quindi senza usare la sottoclasse UIPercentDrivenInteractiveTransition ) allora sei responsabile di gestire la transizione completa (non ne sono sicuro .. scusa ma la documentazione a mio avviso non è chiara).