web-dev-qa-db-fra.com

Afficher clearColor UIViewController sur UIViewController

J'ai une vue UIViewController en tant que sous-vue/modale au-dessus d'une autre vue UIViewController, telle que la sous-vue/modale soit transparente et que tous les composants ajoutés à la sous-vue soient visibles. Le problème est que j'ai la sous-vue montre un fond noir au lieu d'avoir clearColor. J'essaie de faire de UIView un fond clair et non noir. Quelqu'un sait-il ce qui ne va pas? Toute suggestion appréciée.

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];

[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:NO];  

SecondViewController.m

- (void)viewDidLoad 
{
     [super viewDidLoad];
     self.view.opaque = YES;
     self.view.backgroundColor = [UIColor clearColor];
}

RÉSOLU: J'ai corrigé les problèmes. Cela fonctionne si bien pour iPhone et iPad. Contrôleur de vue modale sans fond noir, tout simplement clearColor/transparent. La seule chose que je dois changer, c’est que j’ai remplacé UIModalPresentationFullScreen par UIModalPresentationCurrentContext. Comme c'est simple ça!

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

AVIS: Si vous utilisez une propriété modalPresentationStyle de navigationController:

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

AVIS: La mauvaise nouvelle est que la solution ci-dessus ne fonctionne pas sur iOS 7. La bonne nouvelle est que j'ai résolu le problème pour iOS7! J'ai demandé de l'aide à quelqu'un et voici ce qu'il a dit:

Lors de la présentation modale d'un contrôleur de vue, iOS supprime les contrôleurs de vue situés en dessous de celui-ci de la hiérarchie des vues pour la durée de la présentation. Bien que la vue de votre contrôleur de vue à présentation modale soit transparente, il n’ya rien en dessous, sauf la fenêtre de l’application, qui est noire. iOS 7 a introduit un nouveau style de présentation modal, UIModalPresentationCustom, qui empêche iOS de supprimer les vues situées sous le contrôleur de vue présenté. Toutefois, pour utiliser ce style de présentation modale, vous devez fournir votre propre délégué de transition pour gérer la présentation et les animations de renvoi. Ceci est décrit dans la conférence intitulée "Transitions personnalisées à l'aide de contrôleurs de vue" de WWDC 2013 https://developer.Apple.com/wwdc/videos/?id=218 , qui explique également comment mettre en œuvre votre propre transition. déléguer.

Vous pouvez voir ma solution pour le problème ci-dessus dans iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

147
hightech

RÉSOLU: J'ai corrigé les problèmes. Cela fonctionne si bien pour iPhone et iPad. Contrôleur de vue modale sans fond noir, tout simplement clearColor/transparent. La seule chose que je dois changer est de remplacer UIModalPresentationFullScreen par UIModalPresentationCurrentContext. Comme c'est simple ça!

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

AVIS: Si vous utilisez une propriété modalPresentationStyle de navigationController:

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

AVIS: La mauvaise nouvelle est que la solution ci-dessus ne fonctionne pas sur iOS 7. La bonne nouvelle est que j'ai résolu le problème pour iOS7! J'ai demandé de l'aide à quelqu'un et voici ce qu'il a dit:

Lors de la présentation modale d'un contrôleur de vue, iOS supprime les contrôleurs de vue situés en dessous de celui-ci de la hiérarchie des vues pour la durée de la présentation. Bien que la vue de votre contrôleur de vue à présentation modale soit transparente, il n’ya rien en dessous, sauf la fenêtre de l’application, qui est noire. iOS 7 a introduit un nouveau style de présentation modale, UIModalPresentationCustom, qui empêche iOS de supprimer les vues situées sous le contrôleur de vues présenté. Toutefois, pour utiliser ce style de présentation modale, vous devez fournir votre propre délégué de transition pour gérer la présentation et les animations de renvoi. Ceci est décrit dans la conférence intitulée "Transitions personnalisées à l'aide de contrôleurs de vue" de WWDC 2013 https://developer.Apple.com/wwdc/videos/?id=218 , qui explique également comment mettre en œuvre votre propre transition. déléguer.

Vous pouvez voir ma solution pour le problème ci-dessus dans iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

138
hightech

iOS8 +

Dans iOS8 +, vous pouvez désormais utiliser le nouveau modalPresentationStyle UIModalPresentationOverCurrentContext pour présenter un contrôleur de vue avec un arrière-plan transparent:

MyModalViewController *modalViewController = [[MyModalViewController alloc] init];
modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;           
[self presentViewController:modalViewController animated:YES completion:nil];    
142
Brody Robertson

Donc, pour les penseurs purement visuels et les fans de storyboard, vous pouvez faire:

1. Contrôleur de vue de présentation

Define context

2. Contrôleur de vue présenté

Presentation: Over Current Context

111
pasevin

Solution Swift 3 & iOS10:

//create view controller
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "RoadTripPreviewViewController")
//remove black screen in background
vc.modalPresentationStyle = .overCurrentContext
//add clear color background
vc.view.backgroundColor = UIColor.clear
//present modal
self.present(vc, animated: true, completion: nil)
21
Kevin ABRIOUX

Ceci est de xCode 7 beta 4 en utilisant un contrôle drag segue. Définissez simplement l’arrière-plan de votre destination de manière à ce qu’il soit effacé, et définissez les propriétés de la division dans IB de la manière suivante (nb. La présentation peut également être "Sur plein écran"):

enter image description here

16
smileBot

J'ai trouvé que le moyen le plus simple de le faire fonctionner sur iOS7 et iOS8 est d'ajouter le paramètre presentationStyle sur UIModalPresentationOverCurrentContext sur modallyPresentedVC (ViewController que vous souhaitez présenter de manière modale) à cause de iOS8:

[modallyPresentedVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[modallyPresentedVC.navigationController setModalPresentationStyle:UIModalPresentationOverCurrentContext];

et UIModalPresentationCurrentContext sur PresentationVC (le contrôleur qui présente modallyPresented) à cause de iOS7:

[presentingVC setModalPresentationStyle:UIModalPresentationCurrentContext];
[presentingVC.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];

Parce que les choses sont gérées différemment sur iOS7 et iOS8. Bien sûr, vous n'avez pas besoin de définir les propriétés de navigationController si vous n'en utilisez pas. J'espère que ça t'as aidé.

8
3vangelos

Version Swift2:

let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewController") as! YourViewController
vc.view.backgroundColor = UIColor.clearColor()
vc.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen // orOverCurrentContext to place under navigation
self.presentViewController(vc, animated: true, completion: nil)
5
Mojtabye

Une autre façon (pas besoin de créer une transition personnalisée et fonctionne sur iOS 7)

tilisation de Storyboard:

Créez le contrôleur de vue enfant avec une taille de liberté, définissez la largeur de la vue sur 500x500 (par exemple) et ajoutez la méthode suivante:

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    self.view.superview.bounds = CGRectMake(0, 0, 500, 500);
    self.view.superview.backgroundColor = [UIColor clearColor];
}

Créez ensuite une séquence modale avec une feuille de formulaire et testez-la.

4
educaPix

solution iOS 7 avec segment personnalisé:

CustomSegue.h
#import <UIKit/UIKit.h>

    @interface CustomSegue : UIStoryboardSegue <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>

    @end



CustomSegue.m
#import "CustomSegue.h"

@implementation CustomSegue

-(void)perform {

    UIViewController* destViewController = (UIViewController*)[self destinationViewController];
    destViewController.view.backgroundColor = [UIColor clearColor];
    [destViewController setTransitioningDelegate:self];
    destViewController.modalPresentationStyle = UIModalPresentationCustom;
    [[self sourceViewController] presentViewController:[self destinationViewController] animated:YES completion:nil];
}


//===================================================================
// - UIViewControllerAnimatedTransitioning
//===================================================================

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

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {

    UIView *inView = [transitionContext containerView];
    UIViewController* toVC = (UIViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    [inView addSubview:toVC.view];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    [toVC.view setFrame:CGRectMake(0, screenRect.size.height, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];

    [UIView animateWithDuration:0.25f
                     animations:^{

                         [toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
                     }
                     completion:^(BOOL finished) {
                         [transitionContext completeTransition:YES];
                     }];
}


//===================================================================
// - UIViewControllerTransitioningDelegate
//===================================================================

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {

    return self;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    //I will fix it later.
    //    AnimatedTransitioning *controller = [[AnimatedTransitioning alloc]init];
    //    controller.isPresenting = NO;
    //    return controller;
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

@end

Solution basée sur du code de haute technologie.

4
Max Gribov

Pour moi cela fonctionne:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"MMPushNotificationViewController"];

    vc.view.backgroundColor = [UIColor clearColor];
    self.modalPresentationStyle = UIModalPresentationCurrentContext;
#ifdef __IPHONE_8_0
    if(IS_OS_8_OR_LATER)
    {
        self.providesPresentationContextTransitionStyle = YES;
        self.definesPresentationContext = YES;
        [vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    }
#endif


    [self presentViewController:vc animated:NO completion:nil];

MMPushNotificationViewController est le contrôleur de la vue transparente et j'ai également rendu la couleur de la vue MMPushNotificationViewController en couleur claire. Maintenant, tout ce que j'ai fait et fait mon contrôleur Transparentview.

3
Manab Kumar Mal

Vous pouvez également "ré-ajouter" la fenêtre à la vue.

OneViewController *vc = [[OneViewController alloc] init];
if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]) {
    [self presentViewController:vc animated:YES completion:nil];
} else {
    [self presentModalViewController:vc animated:YES];
}

[[[UIApplication sharedApplication] keyWindow] insertSubview:self.view atIndex:0];

Et de cette façon, la présentation peut être animée.

2
Elf Sundae

Fonctionne bien sur iOS7 et iOS8

UIViewController* vc=[[UIViewController alloc]initWithNibName:@"VC" bundle:nil];

vc.view.alpha=0.7;
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];

self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;

[self presentViewController:vc animated:NO completion:nil];
2
hoppus

Pour iOS7

Il existe maintenant un moyen d'y parvenir à l'aide des transitions personnalisées iOS7:

MyController * controller = [MyController new];
[controller setTransitioningDelegate:self.transitionController];
controller.modalPresentationStyle = UIModalPresentationCustom;
[self controller animated:YES completion:nil];

Pour créer votre transition personnalisée, vous avez besoin de 2 choses:

  • Un objet TransitionDelegate (implémentant <UIViewControllerTransitionDelegate>)
  • Un objet "AnimatedTransitioning" (implémentant <UIViewControllerAnimatedTransitioning>)

Vous pouvez trouver plus d'informations sur les transitions personnalisées dans ce tutoriel .

2
Kirualex

Pour iOS 7 et uniquement à l'aide d'Interface Builder, cela peut être accompli en réglant la présentation sur "Contexte actuel" sur tous les contrôleurs de vue impliqués dans la présentation modale. même pour les contrôleurs de navigation.

Par exemple, définissez-le sur tous ces contrôleurs de vue:

NavController -> RootViewController -> ModalViewController

enter image description here

1
David Hernandez

Je n'ai pas beaucoup joué avec le constructeur de Storyboard/Interface, mais ce qui m’a fait comprendre, c’est que vous dites que la vue doit être de couleur claire (c’est-à-dire 100% alpha/transparent) et que vous dites également qu’elle est opaque ( 0% alpha - complètement solide). Ces deux choses ne semblent pas enchevêtrées. Je commenterais la ligne self.view.opaque = YES; et verrais si cela fonctionne alors;)

Ah, quelque chose d'autre que je viens de penser - il est tout à fait possible que votre contrôleur de vue a l'arrière-plan alpha, mais bien sûr l'alpha sera visible à travers la couleur de la fenêtre de base ou du contrôleur de vue racine du programme, qui est par noir par défaut. La couche de base même de toute votre application ne peut pas avoir un arrière-plan transparent - transparent à quoi? Qu'y a-t-il derrière? Il doit y avoir quelque chose à voir à travers la transparence. Cela a-t-il du sens?

0
WendiKidd