web-dev-qa-db-fra.com

Appels non équilibrés pour commencer / terminer les transitions d'apparence pour <UINavigationController: 0xa98e050>

Lors de la compilation du code que j'ai obtenu

"Appels non équilibrés pour commencer/terminer les transitions d'apparence pour <UINavigationController: 0xa98e050> "

avertissement.

Voici mon code

KVPasscodeViewController *passcodeController = [[KVPasscodeViewController alloc] init];
passcodeController.delegate = self;

UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:passcodeController];
[(UIViewController *)self.delegate presentModalViewController:passcodeNavigationController animated:YES];
20
KsK

Je sais que c'est une vieille question, mais pour le bien de ceux qui la traversent à nouveau, voici ce que j'ai trouvé.

Premièrement, la question n'indique pas où le nouveau viewController était appelé.
Je soupçonne que cela a été appelé depuis -(void)viewDidLoad

Déplacez le code approprié vers -(void)viewDidAppear: et le problème devrait disparaître.

En effet, à -viewDidLoad, la vue a été chargée, mais n'a pas encore été présentée et les animations et les vues ne sont pas terminées.

Si votre intention est de pousser une fenêtre, faites-le après que la fenêtre a été présentée et peinte.

Si vous vous retrouvez à utiliser des minuteries pour contrôler le comportement du système, demandez-vous ce que vous faites mal ou comment vous pourriez le faire plus correctement.

57
Mark Travis

J'ai constaté que ce problème se produit si vous essayez de pousser le nouveau contrôleur de vue pendant la transaction précédente ( animation ) en cours.

Quoi qu'il en soit, je pense que c'est presentModalViewController problème, Set animated:NO, peut résoudre votre problème

[(UIViewController *)self.delegate presentModalViewController:passcodeNavigationController animated:NO];

L'autre option est:

Prenez NSTimer et appelez le code ci-dessus entre peut être ,50 à 1 seconde. Cette astuce est également utile. donc votre viewController perméable a fait son animation.

17
iPatel

Cet avertissement apparaît lorsque vous essayez de charger un nouveau viewController avant que celui précédemment inclus ne soit terminé. Si vous avez l'intention de le faire, ajoutez simplement votre code à un bloc dispatch_async(dispatch_get_main_queue():

dispatch_async(dispatch_get_main_queue(), ^(void){
        [(UIViewController *)self.delegate presentModalViewController:passcodeNavigationController animated:YES];
});

et l'avertissement disparaîtra.

une solution moderne peut être la suivante:

double delayInSeconds = 0.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds *   NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [self.window.rootViewController presentViewController:yourVC animated:YES completion:nil];
});
3
Harald

Vous n'avez pas fourni beaucoup de contexte, donc je suppose que cette erreur se produit au démarrage car vous présentez un contrôleur de vue de code d'accès.

Afin de se débarrasser de cet avertissement, j'enregistre le délégué de l'application en tant que délégué du contrôleur de vue racine de navigation:

- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ((UINavigationController *)self.window.rootViewController).delegate = self;
    return YES;
}

Ensuite, je présente le contrôleur de vue modale dans navigationController:didShowViewController:animated: avec un dispatch_once:

- (void) navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        KVPasscodeViewController *passcodeController = [[KVPasscodeViewController alloc] init];
        passcodeController.delegate = self;

        UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:passcodeController];
        [(UIViewController *)self.delegate presentViewController:passcodeNavigationController animated:YES completion:nil];
    });
}

Puisque navigationController:didShowViewController:animated: est appelé après l'apparition du contrôleur de vue racine, l'avertissement appels asymétriques pour commencer/terminer les transitions d'apparence a disparu.

1
0xced