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.