Visualizza clearColor UIViewController su UIViewController


150

Ho una UIViewControllervista come sottoview / modale sopra un'altra UIViewControllervista, come quella che la subview / modale dovrebbe essere trasparente e qualsiasi componente aggiunto alla sottoview dovrebbe essere visibile. Il problema è che la vista secondaria mostra uno sfondo nero invece di avere clearColor. Sto provando a fare UIViewcome sfondo ClearColor non nero. Qualcuno sa cosa c'è che non va? Qualche suggerimento apprezzato.

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

RISOLTO : ho risolto i problemi. Funziona così bene sia per iPhone che per iPad. Modal View Controller senza sfondo nero solo chiaroColore / trasparente. L'unica cosa che ho bisogno di cambiamento è ho sostituito UIModalPresentationFullScreena UIModalPresentationCurrentContext. Quanto è semplice!

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

AVVISO: se si utilizza una modalPresentationStyleproprietà di 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];

AVVISO: la cattiva notizia è che la soluzione di cui sopra non funziona su iOS 7. La buona notizia è che ho risolto il problema per iOS7! Ho chiesto aiuto a qualcuno ed ecco cosa ha detto:

Quando si presenta un controller di visualizzazione in modo modale, iOS rimuove i controller di visualizzazione sottostanti dalla gerarchia di visualizzazione per la durata in cui viene presentato. Mentre la vista del controller della vista presentato in modo modale è trasparente, non c'è nulla al di sotto di essa tranne la finestra dell'app, che è nera. iOS 7 ha introdotto un nuovo stile di presentazione modale UIModalPresentationCustom, che impedisce a iOS di rimuovere le visualizzazioni sotto il controller di visualizzazione presentato. Tuttavia, per utilizzare questo stile di presentazione modale, è necessario fornire il proprio delegato di transizione per gestire la presentazione e chiudere le animazioni. Questo è delineato nel discorso "Transizioni personalizzate usando i controller di visualizzazione" del WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 che illustra anche come implementare il proprio delegato di transizione.

Puoi vedere la mia soluzione per il problema sopra in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions


1
assicurati di impostare modalPresentationStyle di rootViewController, altrimenti non funzionerà
— Thorsten

— Dai

Questo stackoverflow.com/q/27598846/1603234 mi fa sorridere, ora è il tuo turno :)
— Hemang

Ho dovuto fare self.modalPresentationStyle = UIModalPresentationCurrentContext; con il controller di visualizzazione presentato per farlo funzionare, non con quello di presentazione.
— Tulleb,

1
Controlla la risposta di Brody qui sotto. modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; risolverà il problema,
— GoodSp33d,

Risposte:


143

iOS 8 +

In iOS8 + è ora possibile utilizzare il nuovo modalPresentationStyle UIModalPresentationOverCurrentContext per presentare un controller di visualizzazione con uno sfondo trasparente:

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

5
Dovrebbe essere la risposta accettata. La risposta precedentemente accettata è ancora valida per motivi legacy, ma questo è il metodo consigliato.
— Tomasz Bąk,

3
Se stai sviluppando solo per iOS 8, vai con questa risposta! Funziona
— Mário Carvalho il

2
Questo va bene, ma non dovrebbe essere l'ultima riga [self presentViewController:modalViewController animated:YES completion:nil];? (invece di targetController)?
— SuperDuperTango

3
Per funzionare, ho aggiunto modalViewController.view.backgroundColor = UIColor.clearColor () grazie per la soluzione
— Pramod

qualcuno può fornirmi il codice anche per il pushviewcontroller (intendo per il controller di navigazione).
— Alok,

140

RISOLTO : ho risolto i problemi. Funziona così bene sia per iPhone che per iPad. Modal View Controller senza sfondo nero solo chiaroColore / trasparente. L'unica cosa che devo modificare è che ho sostituito UIModalPresentationFullScreen in UIModalPresentationCurrentContext. Quanto è semplice!

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

AVVISO: se si utilizza una proprietà modalPresentationStyle di 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];

AVVISO: la cattiva notizia è che la soluzione di cui sopra non funziona su iOS 7. La buona notizia è che ho risolto il problema per iOS7! Ho chiesto aiuto a qualcuno ed ecco cosa ha detto:

Quando si presenta un controller di visualizzazione in modo modale, iOS rimuove i controller di visualizzazione sottostanti dalla gerarchia di visualizzazione per la durata in cui viene presentato. Mentre la vista del controller della vista presentato in modo modale è trasparente, non c'è nulla al di sotto di essa tranne la finestra dell'app, che è nera. iOS 7 ha introdotto un nuovo stile di presentazione modale, UIModalPresentationCustom, che impedisce a iOS di rimuovere le visualizzazioni sotto il controller di visualizzazione presentato. Tuttavia, per utilizzare questo stile di presentazione modale, è necessario fornire il proprio delegato di transizione per gestire la presentazione e chiudere le animazioni. Questo è delineato nel discorso "Transizioni personalizzate usando i controller di visualizzazione" del WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218, che illustra anche come implementare il proprio delegato di transizione.

Puoi vedere la mia soluzione per il problema sopra in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions


1
self.modalPresentationStyle = UIModalPresentationCurrentContext;fatto.
— Adriano Lucas,

4
a proposito .. ho osservato che a causa di self.modalPresentationStyle = UIModalPresentationCurrentContext; non presenta modalViewController con animazioni .. qualche idea?
— Devarshi,

1
@Miraaj Quindi impostare modalPresentationStyle su UIModalPresentationFullScreen prima di mostrare UIViewController dovrebbe funzionareself.modalPresentationStyle = UIModalPresentationFullScreen; [self performSegueWithIdentifier:@"CustomSegue" sender:self];
— hightech

1
Eseguendo questo in iOS 6 e 7, il nuovo controller di visualizzazione è chiaro durante l'animazione della presentazione, ma una volta che è in posizione lo sfondo diventa nero. Diventa di nuovo chiaro quando si anima il licenziamento. Qualcun altro ha avuto questo problema?
— Ha disegnato C il

3
@pkamb Ho aggiornato la soluzione per iOS 7. stackoverflow.com/a/11252969/1344459 Spero che ti aiuti.
— hightech,

114

Quindi, per i pensatori puramente visivi e gli appassionati di storyboard, puoi fare:

1. Presentazione di View Controller

Definire il contesto

2. Controller di visualizzazione presentato

Presentazione: sopra il contesto attuale


Questa dovrebbe essere la risposta accettata. Questo è tutto ciò che devi fare per farlo funzionare, quindi impostare il colore di sfondo della vista sul controller modale per cancellare.
— Jesse,

D'accordo, le opzioni dello storyboard sovrascrivono il codice in questo caso.
— C0D3,

17
Questa risposta è così dolce, ora ho il diabete.
— GeneCode

25

Soluzione Swift 3 e 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)

16

Questo è da xCode 7 beta 4 usando un controllo trascinamento segue. Basta impostare lo sfondo della destinazione per cancellare e impostare le seguenti proprietà in IB in questo modo (nb. La presentazione può anche essere "A schermo intero"):

inserisci qui la descrizione dell'immagine


2
GRAZIE. ho fatto la tua correzione segue + la risposta di ViewControllers di @pasevin e ha funzionato !!
— CSawy,

1
Questo ha risposto alla mia domanda. Grazie mille. Votazione up: D
— Nate4436271,

8

Ho trovato il modo più semplice per farlo funzionare su iOS7 e iOS8 è aggiungere impostare la presentazioneStyle a UIModalPresentationOverCurrentContext sul modallyPresentedVC (ViewController che vuoi presentare modalmente) a causa di iOS8:

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

e UIModalPresentationCurrentContext su presentando VC (il controller che presenta il modallyPresented) a causa di iOS7:

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

Perché le cose sono gestite in modo diverso su iOS7 e iOS8. Ovviamente non è necessario impostare le proprietà navigationController se non ne si utilizza una. Spero che aiuti.


mi ha salvato la pancetta! Grazie
— Duck il

5

Versione 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)

4

Un altro modo (non è necessario creare una transizione personalizzata e funziona su iOS 7)

Utilizzando Storyboard:

Crea il controller di visualizzazione figlio con dimensioni di libertà, imposta la larghezza di visualizzazione su 500x500 (ad esempio) e aggiungi il metodo successivo:

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

Quindi creare un seguito modale con il modulo e testarlo.


Sei fantastico!!! questo funziona davvero !!! (l'impostazione della dimensione "libertà" in IB non influisce sull'anima delle cose, è una metrica simulata, ma comunque funziona !!!) ed è così semplice !!!
— Radu Simionescu,

4

Soluzione iOS 7 con follow personalizzato:

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

Soluzione basata sul codice high-tech.


Quando chiudo il da [self dismissViewControllerAnimated: SÌ completamento: NULL]; Ottengo un'eccezione ??
— Asadullah Ali,

Sì per questo codice. Oppure devi implementare il metodo animationControllerForDismissedController per l'animazione per iniziare a lavorare.
— Max Gribov,

4

Per me funziona:

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è il controller Transparent View e ho anche creato il MMPushNotificationViewControllercolore della vista come clearcolor. Ora tutto ciò che ho fatto e realizzato il mio controller Transparentview.


2

Per iOS7

Ora c'è un modo per raggiungere questo obiettivo utilizzando le transizioni personalizzate iOS7, in questo modo:

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

Per creare la tua transizione personalizzata, hai bisogno di 2 cose:

  • Un oggetto TransitionDelegate (implementazione <UIViewControllerTransitionDelegate>)
  • Un oggetto "AnimatedTransitioning" (implementazione <UIViewControllerAnimatedTransitioning>)

Puoi trovare ulteriori informazioni sulle transizioni personalizzate in questo tutorial .


Qualche motivo specifico per cui hai aggiunto mainviewcontroller e la classe controller della seconda vista nella classe animatore? perché non hai usato direttamente UIViewController * toVC = (UIViewController *) [transizioneContext viewControllerForKey: UITransitionContextToViewControllerKey]; UIViewController * fromVC = (UIViewController *) [transizioneContext viewControllerForKey: UITransitionContextFromViewControllerKey];
— Satyam Raikar,

Non è il mio tutorial, quindi non conosco i dettagli di questo. Il tuo punto sembra valido però.
— Kirualex,

2

Funziona alla grande su iOS7 e iOS 8

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

Un duplicato della seconda migliore risposta.
— Tomasz Bąk,

2

Puoi anche "aggiungere nuovamente" la finestra alla vista.

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

E in questo modo, la presentazione può essere animata.


1

Per iOS 7 e solo usando Interface Builder può essere realizzato impostando la Presentazione su "Over Current Context" su tutti i controller di vista coinvolti nella presentazione modale. Anche per i controller di navigazione.

Ad esempio, impostalo su tutti questi controller di visualizzazione:

NavController -> RootViewController -> ModalViewController

inserisci qui la descrizione dell'immagine


0

Non ho mai giocato molto con il costruttore di Storyboard / Interface, ma ciò che mi viene in mente è che stai dicendo alla vista di essere di colore chiaro (cioè 100% alfa / trasparente) e anche che è opaca ( 0% alfa - completamente solido). Queste due cose non sembrano mesh. Vorrei commentare la self.view.opaque = YES;riga e vedere se funziona allora;)

Ah, qualcos'altro che ho appena pensato: è del tutto possibile che il tuo controller di vista abbia lo sfondo alfa, ma ovviamente l'alfa mostrerà attraverso il colore della finestra di base o del controller di vista radice del programma, che è di nero predefinito. Il livello base dell'intera app non può avere uno sfondo trasparente - trasparente per cosa? Cosa c'è dietro? Deve esserci qualcosa da vedere ATTRAVERSO la trasparenza. Ha senso?


Ho provato a commentare self.view.opaque = SÌ; linea e non funziona. :-(
— hightech,

Hai letto la seconda parte della mia risposta? Potrebbe non essere possibile eseguire ciò che si desidera, a seconda della configurazione. Cosa stai posizionando dietro il clearColor VC? Forse possiamo risolvere questo ^^
— WendiKidd il

-3

Usa "self.modalPresentationStyle = UIModalPresentationCurrentContext;", nella vista di presentazione

Funzionerà bene :)


1
Questo è solo ripetere ciò che le risposte esistenti hanno già detto.
— Pang
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.