71 votes

Transparent Modal Vue sur la manette de Navigation

Je suis en train de créer un transparent modal Vue sur le dessus de ma manette de navigation. Personne ne sait si cela est possible?

109voto

phatblat Points 2046

Un modal vue de couvrir la vue, il est poussé sur le dessus de la barre de navigation pour votre manette de navigation. Toutefois, si vous utilisez l'-presentModalViewController:animation: approche, puis une fois que l'animation se termine la vue juste couvertes fait disparaître, ce qui rend toute transparence de votre modal vue inutile. (Vous pouvez vérifier cela par la mise en œuvre de l'-viewWillDisappear: et -viewDidDisappear: méthodes dans la racine de votre vue-contrôleur).

Vous pouvez ajouter la modale de vue directement à la vue de la hiérarchie de la sorte:

UIView *modalView =
    [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
modalView.opaque = NO;
modalView.backgroundColor =
    [[UIColor blackColor] colorWithAlphaComponent:0.5f];

UILabel *label = [[[UILabel alloc] init] autorelease];
label.text = @"Modal View";
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
[label sizeToFit];
[label setCenter:CGPointMake(modalView.frame.size.width / 2,
                                modalView.frame.size.height / 2)];
[modalView addSubview:label];

[self.view addSubview:modalView];

L'ajout de la modalView comme une sous-vue à la vue de la racine comme ce ne sera pas réellement le couvercle de la barre de navigation, mais il permettra de couvrir la totalité de la vue ci-dessous. J'ai essayé de jouer un peu avec l'origine de la base de sondage utilisée pour initialiser le modalView, mais une valeur négative, il ne s'affiche pas. La meilleure méthode que j'ai trouvé pour couvrir la totalité de l'écran en plus de la barre d'état est d'ajouter la modalView comme une sous-vue de la fenêtre elle-même:

TransparentModalViewAppDelegate *delegate = (TransparentModalViewAppDelegate *)[UIApplication sharedApplication].delegate;
[delegate.window addSubview:modalView];

18voto

Murlakatam Points 230

Le plus simple est d'utiliser modalPresentationStyle propriété de navigationController (mais vous aurez à faire de l'animation par vous-même):

self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalViewController animated:NO];
modalViewController.view.alpha = 0;
[UIView animateWithDuration:0.5 animations:^{
    modalViewController.view.alpha = 1;
}];

12voto

pix0r Points 17854

- Je y arriver plus facilement par la mise en place d'un "OverlayViewController" qui se trouve au-dessus de tous les autres sous-vues de ma fenêtre ou de la racine de la vue. Mis cela dans votre délégué d'application ou de la racine-vue-contrôleur, et de faire OverlayViewController un singleton de sorte qu'il peut être consulté à partir de n'importe où dans votre code ou de la vue contrôleur de la hiérarchie. Vous pouvez appeler les méthodes pour afficher les points de vue modal, montrent les indicateurs d'activité, etc, à chaque fois que vous en avez besoin, et ils peuvent éventuellement couvrir toute l'onglet barres de navigation ou de contrôleurs.

Exemple de code pour la vue de la racine de contrôleur:

- (void)viewDidLoad {
  OverlayViewController *o = [OverlayViewController sharedOverlayViewController];
  [self.view addSubview:o.view];
}

Exemple de code que vous pouvez utiliser pour afficher votre modal vue:

[[OverlayViewController sharedOverlayViewController] presentModalViewController:myModalViewController animated:YES];

Je n'ai pas réellement utilisé -presentModalViewController:animated: avec mon OverlayViewController mais j'espère que cela serait très bien fonctionner.

Voir aussi: Quel est votre Objectif-C singleton?

8voto

cfisher Points 4915

J'ai eu ce même problème et pour La solution consiste à ajouter le modal vue avec addSubview: et animer le changement dans le point de vue de la hiérarchie avec UIView de animateWithDuration:délai:options:animations:achèvement:

J'ai ajouté une propriété et de 2 méthodes pour une sous-classe de UIViewController (FRRViewController) qui comprend d'autres fonctionnalités. J'ai l'intention de publier l'ensemble de trucs sur gitHub bientôt, mais en attendant, vous pouvez voir le code ci-dessous. Pour plus d'informations, vous pouvez consulter mon blog: Comment faire pour afficher un transparent modal-vue-contrôleur.

#pragma mark - Transparent Modal View
-(void) presentTransparentModalViewController: (UIViewController *) aViewController 
                                     animated: (BOOL) isAnimated 
                                    withAlpha: (CGFloat) anAlpha{

    self.transparentModalViewController = aViewController;
    UIView *view = aViewController.view;

    view.opaque = NO;
    view.alpha = anAlpha;
    [view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        UIView *each = obj;
        each.opaque = NO;
        each.alpha = anAlpha;
    }];

    if (isAnimated) {
        //Animated
        CGRect mainrect = [[UIScreen mainScreen] bounds];
        CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);


        [self.view addSubview:view];
        view.frame = newRect;

        [UIView animateWithDuration:0.8
                         animations:^{
                             view.frame = mainrect;
                         } completion:^(BOOL finished) {
                             //nop
                         }];

    }else{
        view.frame = [[UIScreen mainScreen] bounds];
        [self.view addSubview:view];
    }






}

-(void) dismissTransparentModalViewControllerAnimated:(BOOL) animated{

    if (animated) {
        CGRect mainrect = [[UIScreen mainScreen] bounds];
        CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);
        [UIView animateWithDuration:0.8
                         animations:^{
                             self.transparentModalViewController.view.frame = newRect;
                         } completion:^(BOOL finished) {
                             [self.transparentModalViewController.view removeFromSuperview];
                             self.transparentModalViewController = nil;
                         }];
    }


}

7voto

n13 Points 1506

Voici ce que j'ai fait pour résoudre le problème de Google sur les détails, mais cette approche a très bien fonctionné pour moi:

  • Prendre une capture d'écran de la vision sous-jacente. https://devforums.apple.com/message/266836 - cela conduit à une méthode qui retourne une UIView pour l'écran actuel.
  • La main la capture d'écran de la vue modal (j'ai utilisé une propriété)
  • Présenter le modal vue
  • Dans le modèle-vue-contrôleur de viewDidAppear, définir l'image comme UIImageView à l'indice 0. Régler la position verticale de l'image en fonction de la hauteur de la barre d'état.
  • Dans le modèle-vue-contrôleur de viewWillDisappear, retirez à nouveau l'image

L'effet est le suivant:

  • Le point de vue anime en tant que n'importe modal point de vue n'est - semi transparent parties du modal vue de faire glisser la vue existante
  • Dès que l'animation s'arrête, l'arrière-plan est la capture d'écran - ce qui le fait apparaître comme si l'ancien point de vue est encore en dessous, même si elle ne l'est pas.
  • Dès que le modal de la vue disparaître animation commence, l'image est supprimée. L'OS pendant ce temps, le vieux mode de navigation, de sorte que le modal afficher de manière transparente glisse loin et hors de la vue comme vous le souhaitez.

J'ai essayé de l'animation dans mon propre superposition de vue mais il ne fonctionne pas très bien. J'ai eu un accident avec aucune indication quant à ce qui est tombé en panne. Plutôt que de chasser cette baisse, je ne le bg vue et Fonctionne vraiment bien.

Code modale point de vue - je pense que vous pouvez comprendre le reste, à savoir la définition de la propriété modalView.bgImage...

- (void)viewDidAppear:(BOOL)animated {
    // background
    // Get status bar frame dimensions
    CGRect statusBarRect = [[UIApplication sharedApplication] statusBarFrame];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:self.bgImage];
    imageView.tag = 5;
    imageView.center = CGPointMake(imageView.center.x, imageView.center.y - statusBarRect.size.height);
    [self.view insertSubview:imageView atIndex:0];
}

- (void)viewWillDisappear:(BOOL)animated {
    [[self.view viewWithTag:5] removeFromSuperview];
}

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