Come utilizzare presentModalViewController per creare una vista trasparente

Sto visualizzando una vista modale con

[self presentModalViewController:controller animated:YES]; 

Quando la vista si sposta verso l’alto dello schermo è trasparente secondo l’impostazione nel file xib da cui è stata creata, ma una volta che riempie lo schermo diventa opaco.

Esiste comunque la possibilità di mantenere la visione trasparente?

Ho il sospetto che la vista su cui è stata posizionata non venga resa piuttosto che la vista modale diventi opaca.

La tua vista è ancora trasparente, ma una volta che il tuo controller modale è in cima alla pila, la vista dietro di essa è nascosta (come nel caso di qualsiasi controller di visualizzazione più in alto). La soluzione è quella di animare manualmente una vista tu stesso; quindi il controller dietro-vista non sarà nascosto (dal momento che non lo avrai lasciato).

Dopo iOS 3.2 c’è un metodo per farlo senza “trucchi” – vedi la documentazione per la proprietà modalPresentationStyle . Hai un rootViewController che presenterà viewController. Quindi ecco il codice per il successo:

 viewController.view.backgroundColor = [UIColor clearColor]; rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext; [rootViewController presentModalViewController:viewController animated:YES]; 

Con questo metodo lo sfondo di viewController sarà trasparente e il rootViewController sottostante sarà visibile. Si prega di notare che questo sembra funzionare solo su iPad, vedere i commenti qui sotto.

Quello di cui avevo bisogno per farlo funzionare:

 self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext; 

Per coloro che vogliono vedere del codice, ecco cosa ho aggiunto al controller della mia vista trasparente:

 // Add this view to superview, and slide it in from the bottom - (void)presentWithSuperview:(UIView *)superview { // Set initial location at bottom of superview CGRect frame = self.view.frame; frame.origin = CGPointMake(0.0, superview.bounds.size.height); self.view.frame = frame; [superview addSubview:self.view]; // Animate to new location [UIView beginAnimations:@"presentWithSuperview" context:nil]; frame.origin = CGPointZero; self.view.frame = frame; [UIView commitAnimations]; } // Method called when removeFromSuperviewWithAnimation's animation completes - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { if ([animationID isEqualToString:@"removeFromSuperviewWithAnimation"]) { [self.view removeFromSuperview]; } } // Slide this view to bottom of superview, then remove from superview - (void)removeFromSuperviewWithAnimation { [UIView beginAnimations:@"removeFromSuperviewWithAnimation" context:nil]; // Set delegate and selector to remove from superview when animation completes [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; // Move this view to bottom of superview CGRect frame = self.view.frame; frame.origin = CGPointMake(0.0, self.view.superview.bounds.size.height); self.view.frame = frame; [UIView commitAnimations]; } 

Il modo approvato da Apple per farlo in iOS 8 è impostare modalPresentationStyle su “UIModalPresentationOverCurrentContext”.

Dalla documentazione di UIViewController:

UIModalPresentationOverCurrentContext

Uno stile di presentazione in cui il contenuto viene visualizzato solo sul contenuto del controllore della visualizzazione padre. Le viste al di sotto del contenuto presentato non vengono rimosse dalla gerarchia della vista al termine della presentazione. Quindi se il controller della vista presentato non riempie lo schermo di contenuti opachi, il contenuto sottostante viene visualizzato.

Quando si presenta un controller di visualizzazione in un popover, questo stile di presentazione è supportato solo se lo stile di transizione è UIModalTransitionStyleCoverVertical. Il tentativo di utilizzare un diverso stile di transizione triggers un’eccezione. Tuttavia, è ansible utilizzare altri stili di transizione (ad eccezione della transizione a ricciolo parziale) se il controller di visualizzazione padre non si trova in un popover.

Disponibile in iOS 8.0 e versioni successive.

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/

Il video “Visualizza i progressi del controller in iOS 8” del WWDC 2014 è dedicato a questo in dettaglio.

Assicurati di dare al controller della vista presentato un colore di sfondo chiaro (altrimenti apparirà ancora opaco).

C’è un’altra opzione: prima di mostrare il controller modale, cattura uno screenshot dell’intera finestra. Inserisci l’immagine catturata in un UIImageView e aggiungi la vista dell’immagine alla vista del controller che stai per mostrare. Quindi inviare a back. Inserisci un’altra vista sopra la vista dell’immagine (sfondo nero, alfa 0,7). Mostra il tuo controller modale e sembra che sia trasparente. Ho appena provato su iPhone 4 con iOS 4.3.1. Come il fascino

questo è abbastanza vecchio, ma ho risolto lo stesso problema come segue: Poiché ho bisogno di presentare un controller di navigazione in iPhone, l’aggiunta di una sottoview non era una soluzione praticabile.

Quindi quello che ho fatto:

1) Prima di presentare il controller della vista, fai uno screenshot della tua schermata attuale:

 UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0); [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * backgroundImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

2) Creare il controller di visualizzazione che si desidera presentare e aggiungere lo sfondo come sottoview, inviandolo indietro.

 UIViewController * presentingVC = [UIViewController new]; UIImageView * backgroundImageOfPreviousScreen = [[UIImageView alloc] initWithImage:backgroundImage]; [presentingVC.view addSubview:backgroundImageOfPreviousScreen]; [presentingVC.view sendSubviewToBack:backgroundImageOfPreviousScreen]; 

3) Presenta il tuo controller di visualizzazione, ma prima di quello nel nuovo controller di visualizzazione, aggiungi una vista trasparente in viewDidLoad (ho usato ILTranslucentView)

 -(void)viewDidLoad { [super viewDidLoad]; ILTranslucentView * translucentView = [[ILTranslucentView alloc] initWithFrame:self.view.frame]; [self.view addSubview:translucentView]; [self.view sendSubviewToBack:translucentView]; } 

E questo è tutto!

Questo sembra essere rotto in IOS 8, sto usando un controller di navigazione e il contesto che viene visualizzato è il contesto dei menu di navigazione che nel nostro caso è un controller Menu scorrevole.

Stiamo usando pod ‘TWTSideMenuViewController’, ‘0.3’ non è stato controllato per vedere se questo è ancora un problema con la libreria o il metodo sopra descritto.

Questo ha funzionato su iOS 8-9:

1- Imposta lo sfondo del controller di visualizzazione con un alfa

2- aggiungi questo codice:

 TranslucentViewController *tvc = [[TranslucentViewController alloc] init]; self.providesPresentationContextTransitionStyle = YES; self.definesPresentationContext = YES; [tvc setModalPresentationStyle:UIModalPresentationOverCurrentContext]; [self.navigationController presentViewController:tvc animated:YES completion:nil]; 

Ho trascritto le mie scoperte su questo in una domanda diversa , ma il succo è che devi chiamare modalPresentationStyle = UIModalPresentationCurrentContext su tutto ciò che possiede l’intero schermo al momento. La maggior parte delle volte, è qualsiasi cosa sia la [applicazione condivisa di applicazione UIA] .delegate.window’s rootViewController. Potrebbe anche essere un nuovo UIViewController che è stato presentato con modalPresentationStyle = UIModalPresentationFullScreen .

Per favore, leggi il mio altro post molto più dettagliato se ti stai chiedendo come ho risolto questo problema in modo specifico. In bocca al lupo!

So che questa è una domanda piuttosto vecchia. Sono rimasto bloccato su questo problema e sono stato in grado di ottenere un vantaggio da questo thread. Quindi, mettendo qui come ho ottenuto ha funzionato :). Sto usando lo storyboard e ho seguito il ViewController che deve essere presentato. Il controller della vista ha un colore di sfondo trasparente. Ora nell’ispettore Attributes del seguito ho impostato la presentazione su “Over current context”. E ha funzionato per me. Sto sviluppando per iPhone.

Ispettore degli attributi del seguito

Ho creato la libreria open soruce MZFormSheetController per presentare il modulo modulo modale su UIWindow aggiuntivo. È ansible utilizzarlo per presentare il controller della vista modale della trasparenza, persino regolare le dimensioni del controller della vista presentato.

Nelle mie condizioni sto vedendo sullo stesso viewController. Quindi crea un nuovo controller di visualizzazione per tenere UIView. Rendi trasparente la vista impostando la sua proprietà alfa. Quindi con un clic del mouse ho scritto questo codice. Sembra buona.

 UIGraphicsBeginImageContext(objAppDelegate.window.frame.size); [objAppDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIViewController *controllerForBlackTransparentView=[[[UIViewController alloc] init] autorelease]; [controllerForBlackTransparentView setView:viewForProfanity]; UIImageView *imageForBackgroundView=[[UIImageView alloc] initWithFrame:CGRectMake(0, -20, 320, 480)]; [imageForBackgroundView setImage:viewImage]; [viewForProfanity insertSubview:imageForBackgroundView atIndex:0]; [self.navigationController presentModalViewController:controllerForBlackTransparentView animated:YES]; 

E mostra quello che voglio. spero che possa aiutare qualcuno.

Ecco una categoria che ho creato per risolvere il problema.

  // // UIViewController+Alerts.h // #import  @interface UIViewController (Alerts) - (void)presentAlertViewController:(UIViewController *)alertViewController animated:(BOOL)animated; - (void)dismissAlertViewControllerAnimated:(BOOL)animated; @end // // UIViewController+Alerts.m // #import "UIViewController+Alerts.h" @implementation UIViewController (Alerts) - (void)presentAlertViewController:(UIViewController *)alertViewController animated:(BOOL)animated { // Setup frame of alert view we're about to display to just off the bottom of the view [alertViewController.view setFrame:CGRectMake(0, self.view.frame.size.height, alertViewController.view.frame.size.width, alertViewController.view.frame.size.height)]; // Tag this view so we can find it again later to dismiss alertViewController.view.tag = 253; // Add new view to our view stack [self.view addSubview:alertViewController.view]; // animate into position [UIView animateWithDuration:(animated ? 0.5 : 0.0) animations:^{ [alertViewController.view setFrame:CGRectMake(0, (self.view.frame.size.height - alertViewController.view.frame.size.height) / 2, alertViewController.view.frame.size.width, alertViewController.view.frame.size.height)]; }]; } - (void)dismissAlertViewControllerAnimated:(BOOL)animated { UIView *alertView = nil; // find our tagged view for (UIView *tempView in self.view.subviews) { if (tempView.tag == 253) { alertView = tempView; break; } } if (alertView) { // clear tag alertView.tag = 0; // animate out of position [UIView animateWithDuration:(animated ? 0.5 : 0.0) animations:^{ [alertView setFrame:CGRectMake(0, self.view.frame.size.height, alertView.frame.size.width, alertView.frame.size.height)]; }]; } } @end 

Il modo alternativo è usare una “vista container”. Basta fare alpha sotto 1 e incorporare con seque. XCode 5, target iOS7.

non posso mostrare l’immagine, non abbastanza reputazione)))

Vista contenitore disponibile da iOS6.

Questo codice funziona perfettamente su iPhone con iOS6 e iOS7:

 presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha' presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext; [presentingVC presentViewController:presentedVC animated:YES completion:NULL]; 

Ma in questo modo perdi l’animazione ‘slide-from-the-bottom’.

Ho trovato questa soluzione elegante e semplice per iOS 7 e versioni successive!

Per iOS 8 Apple ha aggiunto UIModalPresentationOverCurrentContext, ma non funziona con iOS 7 e versioni precedenti, quindi non è stato ansible utilizzarlo per il mio caso.

Per favore, crea la categoria e inserisci il seguente codice.

.h file

 typedef void(^DismissBlock)(void); @interface UIViewController (Ext) - (DismissBlock)presentController:(UIViewController *)controller withBackgroundColor:(UIColor *)color andAlpha:(CGFloat)alpha presentCompletion:(void(^)(void))presentCompletion; @end 

.m file

 #import "UIViewController+Ext.h" @implementation UIViewController (Ext) - (DismissBlock)presentController:(UIViewController *)controller withBackgroundColor:(UIColor *)color andAlpha:(CGFloat)alpha presentCompletion:(void(^)(void))presentCompletion { controller.modalPresentationStyle = UIModalPresentationCustom; UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; __block UIView *overlay = [[UIView alloc] initWithFrame:keyWindow.bounds]; if (color == nil) { color = [UIColor blackColor]; } overlay.backgroundColor = color; overlay.alpha = alpha; if (self.navigationController != nil) { [self.navigationController.view addSubview:overlay]; } else if (self.tabBarController != nil) { [self.tabBarController.view addSubview:overlay]; } else { [self.view addSubview:overlay]; } self.modalPresentationStyle = UIModalPresentationCurrentContext; [self presentViewController:controller animated:true completion:presentCompletion]; DismissBlock dismissBlock = ^(void) { [self dismissViewControllerAnimated:YES completion:nil]; [UIView animateWithDuration:0.25 animations:^{ overlay.alpha = 0; } completion:^(BOOL finished) { [overlay removeFromSuperview]; }]; }; return dismissBlock; } @end 

Nota: funziona anche per navigationContoller, tabBarController.

Esempio di utilizzo:

  // Please, insure that your controller has clear background ViewController *controller = [ViewController instance]; __block DismissBlock dismissBlock = [self presentController:controller withBackgroundColor:[UIColor blackColor] andAlpha:0.5 presentCompletion:nil]; // Supposed to be your controller's closing callback controller.dismissed = ^(void) { dismissBlock(); }; 

Divertirsi! e per favore, lascia un feedback.

Dopo molte ricerche sembra che questo risolva il nostro problema e serva ai nostri scopi.

creare un seguito dalla sorgente VC alla destinazione VC con un identificatore.

ad esempio “goToDestinationViewController” ok per rendere le vite facili consideriamo il controller di visualizzazione corrente, ovvero, quello che vuoi dietro la tua vista trasparente come sorgente e la destinazione come destinazione

Ora nella sorgente VC in viewDidLoad: o view

 performSegueWithIdentifier("goToDestinationViewController", sender: nil) 

bene siamo a metà. Ora vai al tuo storyboard. Clicca sul seguito. che dovrebbe assomigliare a questo: segue

cambia le opzioni in ciò che viene mostrato.

Ora arriva la vera soluzione.

nella vista di destinazione viewDidLoad del controller aggiungere questo codice.

 self.modalPresentationStyle = .Custom 

………………………………………….. …………………..COSÌ FACILE……………………. …………………………………..

Questo è il modo migliore e più pulito che ho trovato finora:

 @protocol EditLoginDelegate  - (void)dissmissEditLogin; @end - (IBAction)showtTransparentView:(id)sender { UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"foo bar" delegate:self cancelButtonTitle:@"cancel" destructiveButtonTitle:@"destructive" otherButtonTitles:@"ok", nil]; [actionSheet showInView:self.view]; } - (void)willPresentActionSheet:(UIActionSheet *)actionSheet{ UIStoryboard *loginStoryboard = [UIStoryboard storyboardWithName:@"Login" bundle:nil]; self.editLoginViewController = [loginStoryboard instantiateViewControllerWithIdentifier:@"EditLoginViewController"]; self.editLoginViewController.delegate = self; [self.editLoginViewController viewWillAppear:NO]; [actionSheet addSubview:self.editLoginViewController.view]; [self.editLoginViewController viewDidAppear:NO]; } 

La soluzione migliore che ho trovato è quella di utilizzare il metodo addChildViewController. Ecco un esempio eccellente: aggiungi la vista di un controller di visualizzazione figlio a una sottoview del controllore della vista genitore

Provo a utilizzare più metodi per risolvere, ma ancora fallito, il codice seguente è stato implementato alla fine.

La risoluzione di Swift:

 // A.swift init method modalPresentationStyle = .currentContext // or overCurrentContent modalTransitionStyle = .crossDissolve // dissolve means overlay 

quindi in B view controller:

 // B.swift let a = A() self.present(a, animated: true, completion: nil)