73 votes

iOS7 UIModalTransitionStyleFlipHorizontal rebondit après la transition

Je suis à jour de mes applications pour iOS 7 et j'ai découvert un problème bizarre. Je vais présenter un UIViewController enveloppé dans un UINavigationController avec UIModalTransitionStyleFlipHorizontal.

Dans iOS 6, il fonctionne très bien, mais dans iOS 7, la barre de navigation rebondit après la transition. Est ce que cela a quelque chose à faire avec la barre d'état? J'ai mis la transparence de la barre de navigation principale d' NO.

Dans l'Info.plist, Vue, contrôleur d'état basé sur l'apparence de la barre est définie sur NON.

J'ai enregistré une petite vidéo (MOV) pour montrer mon problème. Et voici un GIF montrant le même problème en un minimum de démonstration de l'application:

enter image description here

Voici mon code:

feedNavigationController = [[UINavigationController alloc] init];
feedNavigationController.navigationBar.translucent = NO;

SettingsViewController *settingsVC = [[SettingsViewController alloc] init];

feedNavigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[feedNavigationController setViewControllers:[NSArray arrayWithObjects:settingsVC, nil]];

[self presentViewController:feedNavigationController animated:YES completion:nil];

54voto

Ben Packard Points 3441

Cela semble être une UIKit bug. La solution de contournement suivante semble résoudre le problème pour moi.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.navigationController.navigationBar.layer removeAllAnimations];
}

(Placez ce dans la vue contrôleur de transition pour).

16voto

EricD Points 343

Pour résoudre ce problème pour le présent et de faire disparaître, j'utilise le iOS7 transition personnalisée.

Ajoutez ceci à votre UIViewController :

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    return (id<UIViewControllerAnimatedTransitioning>)self;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    return (id<UIViewControllerAnimatedTransitioning>)self;
}

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

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
    UIView *containerView = [transitionContext containerView];


    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    [containerView addSubview:fromVC.view];

    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    [containerView addSubview:toVC.view];

    UIViewAnimationOptions animationOption = ([toVC.presentedViewController isEqual:fromVC])?UIViewAnimationOptionTransitionFlipFromLeft:UIViewAnimationOptionTransitionFlipFromRight;


    [UIView transitionFromView:fromVC.view
                        toView:toVC.view
                      duration:[self transitionDuration:transitionContext]
                       options:animationOption
                    completion:^(BOOL finished) {
                        [transitionContext completeTransition:YES];
                    }];
}

Pour l'utiliser, vous avez juste à vérifier si vous êtes sur iOS7 et définir la transitionDelegate :

YourVCWithTheCustomTransition* yourVC = [[YourVCWithTheCustomTransition alloc] init];

CGFloat deviceVersion = [UIDevice currentDevice].systemVersion.floatValue;
if(deviceVersion >= 7.0) [yourVC setTransitioningDelegate:yourVC];

[self presentModalViewController:yourVC animated:YES];
[yourVC release];

Dans mon cas, j'ai eu une coutume UINavigationController où la coutume de transition est définie : je n'ai pas à le faire à chaque fois.

9voto

dusty Points 239

Cela semble être une UIKit bug. La solution de contournement suivante semble résoudre le problème pour moi.

presentViewController (placez ce dans la vue contrôleur de transition):

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.navigationController.navigationBar.layer removeAllAnimations];
}

dismissViewControllerAnimated (placez ce dans la vue contrôleur de vous licencier pour):

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];

    [self.navigationController.navigationBar.layer removeAllAnimations];
}

si vous n'utilisez pas de mise en page automatique. vous avez besoin d'ajouter cela à la vue du contrôleur de vous licencier pour:

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    [self.view setNeedsLayout];
} 

3voto

RemeR Points 135

J'ai eu le même problème et pourrait "résoudre" (c'est pas une vraie solution au problème, mais il a l'air bien :) ). L'astuce est de présenter le point de vue du contrôleur à l'aide de pushViewController/popViewController avec une UIView animation pour faire un flip. Voici un exemple de code pour présenter le point de vue du contrôleur:

UIViewController *viewController = [[UIViewController alloc] init];
[UIView transitionWithView:self.navigationController.view 
                  duration:0.5 
                   options:UIViewAnimationOptionTransitionFlipFromLeft 
                animations:^{
                   [self.navigationController pushViewController:viewController animated:NO];
                }
                completion:nil];

De le rejeter:

[UIView transitionWithView:self.navigationController.view 
                  duration:0.5 
                   options:UIViewAnimationOptionTransitionFlipFromRight 
                animations:^{
                   [self.navigationController popViewControllerAnimated:NO];
                }
                completion:nil];

Si vous ne voulez pas le navigationBar sur l'poussé contrôleur appelez simplement auto.navigationController setNavigationBarHidden:OUI animation:NON] dans viewWillAppear. J'espère que cette approche vous aider

1voto

Ortwin Gentz Points 15102

Pour la présentation et la vue-contrôleur, j'ai un UITableViewController dans UINavigationController, à la fois configuré à l'aide de Mise en page Automatique. J'ai remarqué que les autres réponses ne résout pas le problème que sur les rejeter la tableView de la présentation-vue-contrôleur sauts 20 pt verticalement.

Cette solution répond à ce problème.

Dans la vue-contrôleur (comme proposé par Ben Packard):

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController.navigationBar.layer removeAllAnimations];
}

Dans la présentation de-vue-contrôleur (comme proposé dans le cadre de poussière):

- (void)viewWillLayoutSubviews{
    if (self.navigationController.presentedViewController) {
        [self.navigationController.navigationBar.layer removeAllAnimations];
        [self.tableView.layer removeAllAnimations];
    }
    [super viewWillLayoutSubviews];
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X