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 ?

3voto

iluvatar_GR Points 656

Fonctionne pour iOS 7-10

if #available(iOS 8.0, *) {
    nextVC.modalPresentationStyle = .OverCurrentContext
    self.presentViewController(nextVC, animated: true, completion: nil)
} else {
    // Fallback on earlier version
    self.modalPresentationStyle = .Custom          
    nextVC.modalTransitionStyle = .CrossDissolve            
    self.presentViewController(nextVC, animated: false, completion: nil)
    }
}

2voto

Segev Points 6481

Pour récapituler toutes les bonnes réponses et tous les commentaires ici et pour avoir une animation tout en déménageant dans votre nouvelle maison, je vous invite à vous inscrire. ViewController Voici ce que j'ai fait : (compatible avec iOS 6 et plus)

Si vous utilisez un UINavigationController \ UITabBarController c'est la voie à suivre :

    SomeViewController *vcThatWillBeDisplayed = [self.storyboard instantiateViewControllerWithIdentifier:@"SomeVC"];

    vcThatWillBeDisplayed.view.backgroundColor = [UIColor colorWithRed: 255/255.0 green:255/255.0 blue:255/255.0 alpha:0.50];    

    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:presentedVC animated:YES completion:NULL];

Si tu fais ça, tu perdras ton modalTransitionStyle l'animation. Afin de résoudre ce problème, vous pouvez facilement ajouter à vos SomeViewController cette classe :

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIView animateWithDuration:0.4 animations:^() {self.view.alpha = 1;}
       completion:^(BOOL finished){}];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.alpha = 0;
}

2voto

Santiago Points 137

Bien sûr, vous devez définir UIModalPresentationCurrentContext, mais l'endroit où définir clearColor est également très important ! Vous ne pouvez pas définir l'arrière-plan dans la fonction viewDidLoad, définissez-le avant le chargement de la vue comme dans la fonction Contrôleur de vue racine ou dans le fonction init du contrôleur qui va présenter !

actionController.view.backgroundColor = [UIColor clearColor];
[self presentViewController:actionController animated:YES completion:nil];

ou

- (instancetype)init {

    self = [super initWithNibName:nil bundle:nil];

    if(self) {
        self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
        [self.view setBackgroundColor:[UIColor clearColor]];
    }

    return self;
}

1voto

Ahmed Points 302

Si vous utilisez une segue modale, assurez-vous de la définir comme cette image (vous pouvez désactiver l'animation si vous le souhaitez). enter image description here

1voto

BB9z Points 474

Une méthode complète testée sur iOS 7 et iOS 8.

@interface UIViewController (MBOverCurrentContextModalPresenting)

/// @warning Some method of viewControllerToPresent will called twice before iOS 8, e.g. viewWillAppear:.
- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;

@end

@implementation UIViewController (MBOverCurrentContextModalPresenting)

- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    UIViewController *presentingVC = self;

    // iOS 8 before
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
        UIViewController *root = presentingVC;
        while (root.parentViewController) {
            root = root.parentViewController;
        }

        [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
            [viewControllerToPresent dismissViewControllerAnimated:NO completion:^{
                UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = UIModalPresentationCurrentContext;
                }
                [presentingVC presentViewController:viewControllerToPresent animated:NO completion:completion];
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = orginalStyle;
                }
            }];
        }];
        return;
    }

    UIModalPresentationStyle orginalStyle = viewControllerToPresent.modalPresentationStyle;
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    }
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:completion];
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = orginalStyle;
    }
}

@end

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