web-dev-qa-db-fra.com

Méthode appropriée pour implémenter une transition interactive UIViewController personnalisée à l'aide de UIViewControllerInteractiveTransitioning Delegate Protocol

Je suis intéressé par un exemple concis de la façon de créer une sous-classe NSObject qui implémente le protocole UIViewControllerInteractiveTransitioning pour gérer une transition interactive personnalisée entre deux UIViewControllers. Idéalement en réponse à un geste de balayage. Quelque chose qui ressemble au balayage interactif par défaut d'iOS7 qui vient maintenant avec UINavigationController, mais un exemple d'implémentation personnalisée/manuelle de cela.

J'ai lu les documents:

Et regardé quelques exemples ailleurs:

  • n
  • deux
  • trois
  • quatre (J'ai mis cela en place mais il s'agit plus de UIViewControllercontainment et de l'implémentation manuelle de ces transitions plutôt que UIViewControllerInteractiveTransitioning

Les documents sont assez clairs mais ne font référence à aucun exemple de code. Et les exemples laissent un peu à désirer (questions sans réponse sur la façon dont les différentes pièces sont liées).

Mes questions sont donc:

  1. Quelqu'un peut-il aider à remplir les blancs sur la façon de lier un geste (par exemple un balayage) à l'objet qui implémente le protocole UIViewControllerInteractiveTransitioning?
  2. Quelle est la relation entre un objet implémentant le protocole UIViewControllerInteractiveTransitioning et celui implémentant le protocole UIViewControllerAnimatedTransitioning? On dirait que vous devez avoir les deux pour déclencher des transitions interactives ...

Merci d'avance...

44
Alfie Hanssen

1) La façon la plus simple de lier un geste à l'objet UIViewControllerInteractiveTransitioning est d'en faire une sous-classe de UIPercentDrivenInteractiveTransition. Ensuite, lorsque vous implémentez le gestionnaire de gestes, vous appelez updateInteractiveTransition: voici un exemple avec du code:

-(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;
      }
    }
}

Ce code provient de https://www.captechconsulting.com/blogs/ios-7-tutorial-series-custom-navigation-transitions--more

2) La fonction animateTransition de UIViewControllerAnimatedTransitioning est utilisée pour effectuer la transition interactive. Il est automatiquement partitionné en "images clés" grâce à votre précédent appel à updateInteractiveTransition. Mais je suppose que si vous implémentez votre startInteractiveTransition: méthode de UIViewControllerInteractiveTransitioning (donc sans utiliser la sous-classe UIPercentDrivenInteractiveTransition) alors vous êtes responsable de gérer la transition complètement (pas sûr de ça .. désolé mais la documentation à mon avis n'est pas vraiment claire) .

12
MatterGoal

Apple fournit en effet un exemple de projet maintenant pour savoir comment vous pouvez y parvenir. Cela dit, je ne pense pas que ce soit l'exemple le plus fin/le plus clair, mais il devrait vous mettre sur la bonne voie.

Ils ont également ne vidéo de la WWDC qui vous guide à travers ce projet.

Soyez averti que c'est un exemple assez complexe, mais si vous parvenez à le séparer et à comprendre les différentes pièces, vous devriez être équipé pour faire face à plus ou moins n'importe quoi sur le front de la transition.

Essentiellement, le projet divise le problème en deux classes d'assistance, 1) un AssetTransitionController qui est initialisé avec et existe pour la durée de vie du contrôleur de vue, et 2) un objet AssetTransitionDriver qui est créé au début et existe pour la durée d'une transition.

Le AssetTransitionController est assez simple, il est conforme à UIViewControllerAnimatedTransitioning et UIViewControllerInteractiveTransitioning gérant le cycle de vie du AssetTransitionDriver.

La AssetTransitionDriver est une simple sous-classe NSObject mais finit en fait beaucoup plus complexe. Il gère le UIViewPropertyAnimator principal, créant la hiérarchie des vues pour la transition et répond au pilote d'interaction (un identificateur de mouvement de panoramique). Il propose également son animateur au AssetTransitionController lorsque demandé.

Il n'utilise pas du tout UIPercentDrivenInteractiveTransition.

6
Tricky