192 votes

iOS : ViewController modal avec arrière-plan transparent

J'essaie de présenter un contrôleur de vue de manière modale, avec un arrière-plan transparent. Mon objectif est de permettre à la vue du contrôleur de vue présentateur et du contrôleur de vue présenté d'être affichée en même temps. Le problème est que lorsque l'animation de présentation se termine, la vue du contrôleur de vue présenté disparaît.

- (IBAction)pushModalViewControllerButtonPressed:(id)sender
{
    ModalViewController *modalVC = [[ModalViewController alloc] init];
    [self presentViewController:modalVC animated:YES completion:nil];
}

Je sais que je pourrais simplement ajouter la vue en tant que sous-vue, mais j'aimerais éviter cette solution pour une raison quelconque. Comment pourrais-je la corriger ?

192voto

Jeff C. Points 31

Pour ceux qui essaient de faire fonctionner ce système sous iOS 8, la façon "approuvée par Apple" d'afficher un contrôleur de vue modal transparent consiste à définir les paramètres suivants modalPresentationStyle sur le présent ed contrôleur à UIModalPresentationOverCurrentContext .

Cela peut être fait dans le code, ou en définissant les propriétés de la séquence dans le storyboard.

Extrait de la documentation de UIViewController :

UIModalPresentationOverCurrentContext

Un style de présentation où le contenu est affiché uniquement sur le contenu du contrôleur de vue parent. Les vues situées sous le contrôleur de vue présenté contenu présenté ne sont pas supprimées de la hiérarchie des vues lorsque la présentation fin de la présentation. Ainsi, si le contrôleur de vue présenté ne remplit pas l'écran avec un contenu opaque, le contenu sous-jacent apparaît.

Lors de la présentation d'un contrôleur de vue dans un popover, cette présentation est pris en charge uniquement si le style de transition est UIModalTransitionStyleCoverVertical. Si vous essayez d'utiliser un autre style de transition différent déclenche une exception. Cependant, vous pouvez utiliser d'autres styles de transition styles de transition (à l'exception de la transition curl partielle) si la vue parente parent n'est pas dans un popover.

Disponible à partir de la version 8.0 d'iOS.

https://developer.apple.com/documentation/uikit/uiviewcontroller

La vidéo " View Controller Advancements in iOS 8 " (progrès du contrôleur de vue dans iOS 8) de la WWDC 2014 aborde ce sujet de manière détaillée.

Note :

  • Veillez à donner à votre contrôleur de vue présenté une couleur de fond claire, de peur qu'il ne soit pas réellement transparent !
  • Vous devez définir cette avant présentant c'est le réglage de ce paramètre dans le viewDidLoad du presentedViewController n'aura pas d'effet

110voto

sat20786 Points 966

Dans iOS 8.0 et supérieur, cela peut être fait en définissant la propriété modalPresentationStyle à UIModalPresentationOverCurrentContext

//Set property **definesPresentationContext** YES to avoid presenting over presenting-viewController's navigation bar

self.definesPresentationContext = YES; //self is presenting view controller
presentedController.view.backgroundColor = [YOUR_COLOR with alpha OR clearColor]
presentedController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

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

See Image Attached

106voto

S.P. Points 1756

Le code suivant ne fonctionne que sur l'iPad.

self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalVC animated:YES];

J'opterais pour l'ajout d'une vue secondaire.

Voici une très bonne discussion. Regardez les commentaires en particulier. Pas seulement la réponse.

Vue modale

Si j'étais toi, je ne le ferais pas. J'ajouterais une vue secondaire et je le ferais. Cela semble me donner un meilleur contrôle sur les choses.

EDIT :

Comme mentionné par Paul Linsay, depuis iOS 8, il suffit de UIModalPresentationOverFullScreen pour le modalPresentationStyle du ViewController présenté. Cela couvre également les boutons de la barre de navigation et de la barre d'onglets.

44voto

malex Points 2992

Ce code fonctionne bien sur l'iPhone sous iOS6 et iOS7 :

presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];

Dans ce cas, vous manquez l'animation slide-on. Pour conserver l'animation, vous pouvez toujours utiliser l'extension "non élégante" suivante :

[presentingVC presentViewController:presentedVC animated:YES completion:^{
    [presentedVC dismissViewControllerAnimated:NO completion:^{
        presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
        [presentingVC presentViewController:presentedVC animated:NO completion:NULL];
    }];
}];

Si notre presentingV est situé à l'intérieur de UINavigationController ou UITabbarController, vous devez opérer avec ces contrôleurs en tant que presentingVC.

En outre, dans iOS7, vous pouvez mettre en œuvre une animation de transition personnalisée en appliquant les règles suivantes UIViewControllerTransitioningDelegate protocole. Bien sûr, dans ce cas, vous pouvez obtenir un fond transparent

@interface ModalViewController : UIViewController <UIViewControllerTransitioningDelegate>

Tout d'abord, avant de présenter, vous devez définir modalPresentationStyle

modalViewController.modalPresentationStyle = UIModalPresentationCustom;

Vous devez ensuite mettre en œuvre deux méthodes de protocole

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    CustomAnimatedTransitioning *transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = YES;
    return transitioning;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    CustomAnimatedTransitioning * transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = NO;
    return transitioning;
}

La dernière chose à faire est de définir votre transition personnalisée dans la section CustomAnimatedTransitioning classe

@interface CustomAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic) BOOL presenting;
@end

@implementation CurrentContextTransitionAnimator

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

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

    if (self.presenting) {
        // custom presenting animation
    }
    else {
        // custom dismissing animation
    }
}

21voto

Bastian Points 394

J'ai eu un peu de mal avec l'Interface Builder de XCode 7 pour définir le style de présentation comme @VenuGopalTewari l'a suggéré. Dans cette version, il ne semble pas y avoir de Over Current Context o Over Full Screen mode de présentation de la transition. Ainsi, pour que cela fonctionne, j'ai réglé le mode sur Default :

enter image description here avec enter image description here

En outre, j'ai défini le mode de présentation du contrôleur de vue présenté de manière modale comme suit Over Full Screen :

enter image description here

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