web-dev-qa-db-fra.com

Comment faire une transition Fade / No entre les contrôleurs de vue

Est-il possible de faire une transition de fondu d'entrée et de sortie entre les contrôleurs de vue dans Storyboard. Ou sans transition.

Si c'est possible, quel est le code pour cela?

58
Sjors

Si vous présentez un contrôleur de vue modale, vous pouvez spécifier un modalTransitionStyle de UIModalTransitionStyleCrossDissolve . Si vous faites cela avec une séquence dans votre storyboard, sélectionnez l'inspecteur d'attributs pour la séquence et spécifiez le style de transition à cet endroit:

enter image description here

Si vous présentez le contrôleur de vue par programme, vous pouvez définir votre séquence modale entre les contrôleurs de vue de votre storyboard avec une "transition" de "Dissolution croisée", puis demander au contrôleur de vue source d'effectuer cette séquence:

[self performSegueWithIdentifier:@"presentSegue" sender:sender];

Ou, si vous appelez presentViewController:

UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"YourStoryboardID"];
controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:controller animated:YES completion:nil];

Dans iOS 7, Apple a fourni une nouvelle technologie qui fournit un contrôle riche et robuste pour des transitions hautement personnalisées. Pour plus d'informations, reportez-vous à la vidéo WWDC 2013 Transitions personnalisées à l'aide de contrôleurs de vue .

Mais, par exemple, si vous souhaitez personnaliser les animations Push et pop dans iOS 7 pour qu'elles s'estompent, vous devez spécifier un delegate pour le contrôleur de navigation

- (void)viewDidLoad {
    [super viewDidLoad];

    self.navigationController.delegate = self;
}

Vous implémenteriez alors animationControllerForOperation qui spécifiait les objets animateurs pour pousser et sauter:

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                  animationControllerForOperation:(UINavigationControllerOperation)operation
                                               fromViewController:(UIViewController*)fromVC
                                                 toViewController:(UIViewController*)toVC
{
    if (operation == UINavigationControllerOperationPush)
        return [[PushAnimator alloc] init];

    if (operation == UINavigationControllerOperationPop)
        return [[PopAnimator alloc] init];

    return nil;
}

Vous devrez évidemment implémenter vos animateurs Push et pop personnalisés, tels que:

@interface PushAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

@implementation PushAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController* toViewController   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    [[transitionContext containerView] addSubview:toViewController.view];

    toViewController.view.alpha = 0.0;

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        toViewController.view.alpha = 1.0;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}

@end

Et

@interface PopAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

@implementation PopAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController* toViewController   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    [[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view];

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        fromViewController.view.alpha = 0.0;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}

@end

Il existe également une technique similaire, mais légèrement différente, pour personnaliser les transitions modales (bien que si vous ne faisiez qu'un visage, vous utiliseriez probablement la modalTransitionStyle décrite ci-dessus, sauf s'il y avait une autre personnalisation subtile que vous vouliez employer). Voir ci-dessus Transitions personnalisées à l'aide de contrôleurs de vue pour plus d'informations.

En bout de ligne, les transitions personnalisées pour iOS 7 sont un moyen légèrement compliqué, mais très robuste, de fournir un contrôle énorme sur les animations pour les transitions.

139
Rob

Pour créer une séquence personnalisée, créez une sous-classe de séquence UIStoryboard. Par exemple:

// MCFadeSegue.h
#import <UIKit/UIKit.h>

@interface MCFadeSegue : UIStoryboardSegue

@end

// MCFadeSegue.m
#import <QuartzCore/QuartzCore.h>
#import "MCFadeSegue.h"

@implementation MCFadeSegue

- (void)perform
{
  CATransition *transition = [CATransition animation];
  transition.duration = 0.5;
  transition.type = kCATransitionFade;

  [[[[[self sourceViewController] view] window] layer] addAnimation:transition
      forKey:kCATransitionFade];

  [[self sourceViewController]
      presentViewController:[self destinationViewController]
      animated:NO completion:NULL];
}

@end

Ensuite, dans MainStoryboard.storyboard, choisissez Segue et définissez Style: Custom et Class: MCFadeSegue.

16
Yaroslav Babenko

Push/Pop UIVIewController FadeIn/FadeOut dans Swift

class FadeInPushSegue: UIStoryboardSegue {

    var animated: Bool = true

    override func perform() {

        if var sourceViewController = self.sourceViewController as? UIViewController, var destinationViewController = self.destinationViewController as? UIViewController {

            var transition: CATransition = CATransition()

            transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
            sourceViewController.view.window?.layer.addAnimation(transition, forKey: "kCATransition")
            sourceViewController.navigationController?.pushViewController(destinationViewController, animated: false)


        }
    }

}

class FadeOutPopSegue: UIStoryboardSegue {

    override func perform() {

        if var sourceViewController = self.sourceViewController as? UIViewController, var destinationViewController = self.destinationViewController as? UIViewController {

            var transition: CATransition = CATransition()

            transition.duration = 0.4
            transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
            transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade

            sourceViewController.view.window?.layer.addAnimation(transition, forKey: "kCATransition")
            sourceViewController.navigationController?.popViewControllerAnimated(false)
        }
    }

}
8
Eugene Braginets

Sans avoir besoin de créer une séquence personnalisée, j'ai remonté ce code pour présenter la vue ...

 UIViewController * nextView = [[UIStoryboard storyboardWithName: @ "Main" bundle: nil] instantiateViewControllerWithIdentifier: @ "YOUR_VIEW_CONTROLLER_STORYBOARD_NAME"]; 
 
 NextView.modalTransitionStyle =. U. ]. .____.]

J'espère que cela aide quiconque rencontre cette question!

6
Brandon Roberts

Essaye celui-là.

    let transition: CATransition = CATransition()
    transition.duration = 0.4
    transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.type = kCATransitionFade
    self.navigationController!.view.layer.addAnimation(transition, forKey: nil)

    let vc = self.storyboard?.instantiateViewControllerWithIdentifier("vcID") as! My_ViewController
    self.navigationController?.pushViewController(vc, animated: false)
5
S R Nayak

Ma Swift avec vérification optionnelle!

    let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
    if let stView = storyboard.instantiateViewControllerWithIdentifier("STVC") as? STVC {
        stView.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
        self.navigationController?.presentViewController(stView, animated: true, completion: nil)
    }

Assurez-vous simplement de définir l'ID du storyboard du "Contrôleur de vue" dans IB

4
ioopl

Ce que j'ai fait était d'utiliser Storyboard dans Interface Builder, de connecter les deux viewcontrollers dont vous avez besoin pour vous déplacer vers/depuis et en arrière (maintenez la touche ctrl et faites glisser le clic du Origin viewcontroller vers le destination viewcontroller), et changé les propriétés de transition. J'ai utilisé ce qui suit:

enter image description here

J'ai ensuite utilisé ce qui suit:

[self performSegueWithIdentifier:@"showMovieDetailSegue" sender:self];

lorsque vous voulez le supprimer, il suffit d'appeler cela depuis le viewcontroller d'origine:

[self dismissViewControllerAnimated:YES completion:nil];

Simple et très rapide.

2
Septronic

Push/Pop UIVIewController FadeIn/FadeOut en syntaxe Swift 3 , basée sur Eugene Braginets 's answer =

class FadeInPushSegue: UIStoryboardSegue {

    var animated: Bool = true

    override func perform() {

        let sourceViewController = self.source
        let destinationViewController = self.destination

        let transition: CATransition = CATransition()

        transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
        sourceViewController.view.window?.layer.add(transition, forKey: "kCATransition")
        sourceViewController.navigationController?.pushViewController(destinationViewController, animated: false)

    }

}

class FadeOutPopSegue: UIStoryboardSegue {

    override func perform() {

        let sourceViewController = self.source

        let transition: CATransition = CATransition()

        transition.duration = 0.4
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade

        sourceViewController.view.window?.layer.add(transition, forKey: "kCATransition")
        _ = sourceViewController.navigationController?.popViewController(animated: false)
    }

}
1
Maverick