web-dev-qa-db-fra.com

iOS 8 - Écran vide après avoir quitté le contrôleur de vue avec une présentation personnalisée

Lorsque vous quittez divers contrôleurs de vue à l'aide de UIModalPresentationCustom, l'écran devient noir après que le contrôleur de vue a été congédié, comme si tous les contrôleurs de vue avaient été supprimés de la hiérarchie de vues.

Le délégué de transition est défini correctement, l'animationControllerForPresentedController est demandée et transmise correctement et la transition est terminée une fois l'animation terminée. 

Ce code exact fonctionne parfaitement lorsqu'il est compilé avec le SDK iOS 7, mais est cassé lorsqu'il est compilé avec iOS 8b5. 

63
jaggedcow

C’est parce que vous ajoutez probablement à la fois la présentation

[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey] 

et le présenté 

[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey] 

affichez les contrôleurs sur votre conteneurView dans la méthode (void) animateTransition: (id) transitionContext de votre contrôleur d'animation. Puisque vous utilisez une présentation modale personnalisée, le contrôleur de vue présentation est toujours affiché sous le contrôleur de vue présenté . Maintenant, comme il est toujours visible, vous n'avez pas besoin de l'ajouter à la vue du conteneur. Au lieu de cela ajoutez uniquement le contrôleur de vue présenté à la conteneurView. Devrait ressembler à quelque chose comme ceci dans votre méthode animateTransition: 

UIView *containerView = [transitionContext containerView];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

// Boolean value to determine presentation or dismissal animation
if (self.presenting){        
    [transitionContext.containerView addSubview:toViewController.view];
    // Your presenting animation code
} else {
    // Your dismissal animation code
}
169
DJSK

C’est le genre de question à laquelle les votes élevés et les réponses acceptées répondent et trompent les gens. De longs mots courts.

Tout d'abord, n'utilisez pas UIModalPresentationCustom, ce n'est pas ce que cela ressemble. ( détail )

Deuxièmement, il existe une nouvelle méthode de récupération de/vers les vues dans animateTransition, n'utilisez plus quelque chose comme 'fromVC.view'. ( Pourquoi )

UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];

//Swift
let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)

Maintenant, l'écran noir devrait disparaître.

18
Lcsky

Il semble que j'ai rencontré le même problème, j'utilise Xcode 6 beta5.

J'ai cherché avec Google et trouvé que quelqu'un d'autre avait le même problème, et ils ont dit qu'il s'agissait d'un bug grave dans iOS 8, alors espérons qu'Apple pourra résoudre ce problème rapidement.

https://github.com/TeehanLax/UIViewController-Transitions-Example/issues/5

5
billbai

Peut-être que la hiérarchie des vues est boguée avec le nouveau Xcode ou que c'est un peu différent c'est iOS8 Ce code a fonctionné pour moi. Ajoutez-le tout en laissant le contrôleur dans la méthode animateTransition: transitionContext.

[[UIApplication sharedApplication].keyWindow addSubview:toViewController.view];
toViewController.view.userInteractionEnabled = YES;
2
Gautam Jain

J'ai ajouté le code ci-dessous au bloc d'achèvement de la transition et il l'a corrigé pour moi.

[UIView animateWithDuration:[self transitionDuration:transitionContext] animations: ^{
    // Animation code

 } completion: ^(BOOL finished) {
     // More of your code

     // Add the following line before completing the transition
    [[[UIApplication sharedApplication] keyWindow] sendSubviewToBack:toViewController.view];

    // Complete the transition
    [transitionContext completeTransition:YES];
}];
2
devgeek

J'ai eu le même problème, et ce qui m'a posé problème, c'est que je ne définissais pas le cadre final de toViewController. Voir l'exemple suivant tiré de http://www.appcoda.com/custom-view-controller-transitions-tutorial/

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

    let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
    let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
    let finalFrameForVC = transitionContext.finalFrameForViewController(toViewController)
    let containerView = transitionContext.containerView()
    let bounds = UIScreen.mainScreen().bounds
    toViewController.view.frame = CGRectOffset(finalFrameForVC, 0, bounds.size.height)
    containerView.addSubview(toViewController.view)

    UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: .CurveLinear, animations: {
        fromViewController.view.alpha = 0.5
        toViewController.view.frame = finalFrameForVC
    }, completion: {
        finished in
        transitionContext.completeTransition(true)
        fromViewController.view.alpha = 1.0
    })
} 
0
eliasbagley

Petit conseil: Assurez-vous que votre "De" UIViewController correspond à ce que vous attendez.

    NSLog(@" FROM vc %@" , [[transitionContext  viewControllerForKey:UITransitionContextFromViewControllerKey] description]);

Avait un bug similaire dans mon code dans le passé. Vous pouvez facilement extraire le bon contexte "De" VC.

  UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];  
  fromView =  [[[fromVC childViewControllers] firstObject]  view];
0
smaura777