web-dev-qa-db-fra.com

Présenter un UIViewController modal transparent

J'essaie de créer moi-même un alertView personnalisé (pour iOS7 +), mais je rencontre des difficultés avec la présentation d'alerteView.

J'ai un UIViewController avec un arrière-plan noir (alpha réglé à 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 objet animateur:

-(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];
    }];
}

Le problème est le suivant: le modal VC s'estompe avec la présentation de VC en arrière-plan comme il est supposé le faire, mais lorsque l'animation se termine, la présentation de VC est supprimée l'arrière-plan.

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

Existe-t-il un moyen de garder la présentation VC en arrière-plan sans avoir à en prendre un instantané et à la définir en tant qu'arrière-plan de la vue du VC modal?

14
Imotep

Pour votre information, j'ai finalement transformé mon alerte personnalisée en sous-classe d'UIView pour la "partie popUp". Pour l'afficher, j'ajoute simplement alertView en tant que sous-vue de la fenêtre keyWindow avec les contraintes pour la centrer et place une vue d'arrière-plan noir transparent derrière celle-ci.

Comme ce n'est pas un contrôleur, je dois gérer moi-même la rotation de l'interface utilisateur (uniquement pour iOS 7, l'interface tourne bien avec iOS 8).

1
Imotep

J'ai essayé cette solution et cela fonctionne à la fois 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 ' PresentationViewController ' et ' shownViewController '.

37
Basem Saadawy

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];    
5
arunjos007

Mon cas peut différer du vôtre, mais les informations peuvent être utiles pour la conversation.

Dans Storyboard, j'ai modifié la présentation de mon segue pour indiquer "Sur plein écran" et cela a fonctionné.

2
Carien van Zyl

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

J'espère que cela t'aides.

1
Nameet

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

Les contrôleurs de vue ne sont pas censés être non opaques lorsqu'ils sont présentés en tant que contrôleurs de vue modaux. iOS supprime le contrôleur de vue sous-jacent lorsque l'animation est terminée, afin d'accélérer la composition lorsque le contrôleur de vue présenté est censé occuper tout l'écran. Il n'y a aucune raison de dessiner un contrôleur de vue - ce qui peut être complexe dans sa hiérarchie de vues - 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 */
                 }];

Cependant, cela ne vous laisse pas la possibilité d’utiliser la logique du contrôleur de présentation dans UIViewController. Vous devrez vous représenter vous-même lorsque le contrôleur de vue présenté sera terminé, puis inverser l'animation et supprimer la variable UIWindow de l'écran.

1
Trenskow