Présentez un UIViewController modal transparent

J'essaie de faire un alertView personnalisé (pour iOS7 +) par moi-même, mais j'ai du mal avec la présentation alertView.

J'ai un UIViewController avec un fond noir (alpha mis à 0.25f), et un alertView comme sous-vue.

Quand je veux montrer le alertView, je présente modalement le viewController:

-(void) show { UIWindow* window = [[UIApplication sharedApplication] keyWindow]; self.modalTransitionStyle = UIModalPresentationCustom; self.transitioningDelegate = self; [window.rootViewController presentViewController:self animated:YES completion:nil]; } 

Et voici mon object d'animation:

 -(NSTimeInterval) transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext { NSLog(@"%s",__PRETTY_FUNCTION__); return 2; } -(void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { NSLog(@"%s",__PRETTY_FUNCTION__); UIView* toView = [transitionContext viewForKey:UITransitionContextToViewKey]; toView.alpha = 0; UIView* container = [transitionContext containerView]; [container addSubview:toView]; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ toView.alpha = 0.5; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } 

La chose est la suivante: le VC modal s'estompe avec le VC présent en arrière-plan comme il est censé le faire, mais lorsque l'animation se termine, le VC présentateur est retiré de l'arrière-plan.

Si j'appelle [transitionContext completeTransition:YES]; à la place, le VC de présentation est en arrière-plan mais le VC modal est supprimé à la fin de l'animation, donc je suppose que le context annule la présentation si nous envoyons 'NON'.

Existe-t-il un moyen de garder le CV en arrière-plan sans avoir à faire un instantané de celui-ci et de le définir comme arrière-plan de la vue du VC modal?

J'ai essayé cette solution et cela fonctionne sur iOS 7 et 8:

 if ([[UIDevice currentDevice].systemVersion integerValue] >= 8) { //For iOS 8 presentingViewController.providesPresentationContextTransitionStyle = YES; presentingViewController.definesPresentationContext = YES; presentedViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; } else { //For iOS 7 presentingViewController.modalPresentationStyle = UIModalPresentationCurrentContext; } 

Remarque: Soyez conscient de la différence entre ' presentingViewController ' et ' presentedViewController '.

iOS8 +

Pour iOS8 +, vous pouvez utiliser l'extrait de code ci-dessous

 SecondViewController *secondViewController = [[SecondViewController alloc] init]; secondViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; [self presentViewController:secondViewController animated:YES completion:nil]; 

Mon cas peut différer du vôtre, mais l'information pourrait être utile pour la conversation.

Dans Storyboard, j'ai changé la présentation de mon segue en disant "Over Full Screen" et ça a fait l'affaire.

Je pense que ce que vous voyez est le comportement par défaut d'iOS.

Les controllers de vue ne sont pas censés être non-opaques lorsqu'ils sont présentés comme des controllers de vue modale. iOS supprime le controller de vue sous-jacent lorsque l'animation est terminée, afin d'accélérer la composition lorsque le controller de vue présenté est censé occuper tout l'écran. Il n'y a aucune raison de dessiner un controller de vue – ce qui peut être complexe dans sa hiérarchie de vue – lorsqu'il n'est même pas visible à l'écran.

Je pense que votre seule solution est de faire une présentation personnalisée.

Remarque: je n'ai pas testé cela. Mais ça va quelque chose comme ça.

 /* Create a window to hold the view controller. */ UIWindow *presenterWindow = [[UIWindow alloc] init]; /* Make the window transparent. */ presenterWindow.backgroundColor = [UIColor clearColor]; presenterWindow.opaque = NO; /* Set the window rootViewController to the view controller you want to display as a modal. */ presenterWindow.rootViewController = myModalViewController; /* Setup animation */ CGRect windowEndFrame = [UIScreen mainScreen].bounds; CGRect windowStartFrame = windowEndFrame; /* Adjust the start frame to appear from the bottom of the screen. */ windowStartFrame.origin.y = windowEndFrame.size.height; /* Set the window start frame. */ presenterWindow.frame = windowStartFrame; /* Put the window on screen. */ [presenterWindow makeKeyAndVisible]; /* Perform the animation. */ [UIView animateWithDuration:0.5 delay:.0 options:UIViewAnimationOptionCurveEaseOut animations:^{ presenterWindow.frame = windowEndFrame; } completion:^(BOOL finished){ /* Your transition end code */ }]; 

Cela ne vous laisse toutefois aucune option pour utiliser la logique du controller de vue de présentation dans UIViewController . Vous devrez vous figurer, lorsque le controller de vue présenté est fait, puis inverser l'animation et supprimer l' UIWindow de l'écran.

Le ViewController n'est pas censé être transparent lorsque vous le présentez ou que vous le poussez. Vous pouvez essayer de l'append en tant que sous-vue. Et pour l'effet de transition, changez son image immédiatement après l'ajout comme sous-vue. Faites son cadre quelque part en dehors de la vue visible, puis animez-le pour changer le cadre en vue visible.

J'espère que cela t'aides.

Pour votre information, j'ai finalement fait mon alert personnalisé sur une sous-class de UIView pour la partie "popUp". Pour l'afficher, j'ajoute juste alertView en tant que sous-vue de la keyWindow avec les contraintes pour le centrer, et mettre derrière lui une vue en arrière-plan noir transparent.

Comme ce n'est pas un controller, je dois gérer la rotation de l'interface user par moi-même (seulement pour iOS 7, il tourne bien avec l'interface user dans iOS 8).