Estoy mostrando una vista modal con
[self presentModalViewController:controller animated:YES];
Cuando la vista se mueve hacia arriba en la pantalla, es transparente según la configuración del archivo xib desde el que se creó, pero una vez que llena la pantalla, se vuelve opaca.
¿Existe alguna forma de mantener la vista transparente?
Sospecho que la vista sobre la que se coloca no se está renderizando en lugar de que la vista modal se esté volviendo opaca.
ios
iphone
uiviewcontroller
Darryl Braaten
fuente
fuente
viewcontroller.modalPresentationStyle = .FormSheet
Respuestas:
Su vista sigue siendo transparente, pero una vez que su controlador modal está en la parte superior de la pila, la vista detrás de él está oculta (como es el caso con cualquier controlador de vista superior). La solución es animar manualmente una vista usted mismo; entonces el controlador de vista posterior no estará oculto (ya que no lo habrá 'dejado').
fuente
Después de iOS 3.2, existe un método para hacer esto sin ningún "truco"; consulte la documentación de la propiedad modalPresentationStyle . Tiene un rootViewController que presentará el viewController. Así que aquí está el código del éxito:
viewController.view.backgroundColor = [UIColor clearColor]; rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext; [rootViewController presentModalViewController:viewController animated:YES];
Con este método, el fondo de viewController será transparente y el rootViewController subyacente será visible. Tenga en cuenta que esto solo parece funcionar en el iPad, consulte los comentarios a continuación.
fuente
Over Current Context
como estilo de presentación.Lo que necesitaba para que esto funcionara:
self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
fuente
modalPresentationStyle
en el controlador de vista de presentación (en lugar de en el de la ventanarootViewController
).Para aquellos que quieran ver algo de código, esto es lo que agregué al controlador de mi vista transparente:
// 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]; }
fuente
La forma aprobada por Apple de hacer esto en iOS 8 es establecer modalPresentationStyle en 'UIModalPresentationOverCurrentContext'.
De la documentación de UIViewController:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/
El video 'Ver los avances del controlador en iOS 8' de la WWDC 2014 trata esto con cierto detalle.
Asegúrese de darle al controlador de vista presentado un color de fondo claro (de lo contrario, seguirá apareciendo opaco).
fuente
Hay otra opción: antes de mostrar el controlador modal, capture una captura de pantalla de toda la ventana. Inserte la imagen capturada en un UIImageView y agregue la vista de imagen a la vista del controlador que está a punto de mostrar. Luego envía al reverso. Inserte otra vista sobre la vista de la imagen (fondo negro, alfa 0.7). Muestre su controlador modal y parece que es transparente. Lo acabo de probar en iPhone 4 con iOS 4.3.1. Como encanto.
fuente
esto es bastante antiguo, pero resolví el mismo problema de la siguiente manera: como necesito presentar un controlador de navegación en el iPhone, agregar una subvista no era una solución viable.
Entonces, lo que hice:
1) Antes de presentar el controlador de vista, tome una captura de pantalla de su pantalla actual:
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0); [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * backgroundImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
2) Cree el controlador de vista que desea presentar y agregue el fondo como una subvista, enviándolo al fondo.
UIViewController * presentingVC = [UIViewController new]; UIImageView * backgroundImageOfPreviousScreen = [[UIImageView alloc] initWithImage:backgroundImage]; [presentingVC.view addSubview:backgroundImageOfPreviousScreen]; [presentingVC.view sendSubviewToBack:backgroundImageOfPreviousScreen];
3) Presente su controlador de vista, pero antes de eso en el nuevo controlador de vista, agregue una vista transparente en viewDidLoad (usé ILTranslucentView)
-(void)viewDidLoad { [super viewDidLoad]; ILTranslucentView * translucentView = [[ILTranslucentView alloc] initWithFrame:self.view.frame]; [self.view addSubview:translucentView]; [self.view sendSubviewToBack:translucentView]; }
¡Y eso es todo!
fuente
Escribí mis hallazgos sobre esto en una pregunta diferente , pero la esencia es que debes llamar
modalPresentationStyle = UIModalPresentationCurrentContext
a quien sea que tenga la pantalla completa en este momento. La mayoría de las veces, es lo que sea el rootViewController de [UIApplication sharedApplication] .delegate.window. También podría ser un nuevo UIViewController que se presentómodalPresentationStyle = UIModalPresentationFullScreen
.Por favor, lea mi otra publicación mucho más detallada si se pregunta cómo resolví este problema específicamente. ¡Buena suerte!
fuente
Esto parece estar roto en IOS 8, estoy usando un controlador de navegación y el contexto que se muestra es el contexto de los menús de navegación, que en nuestro caso es un controlador de menú deslizante.
Estamos usando el pod 'TWTSideMenuViewController', '0.3' no ha verificado si esto es un problema con la biblioteca o el método descrito anteriormente.
fuente
Esto funcionó para mí en iOS 8-9:
1- Configura el fondo de tu controlador de vista con un alfa
2- agrega este código:
TranslucentViewController *tvc = [[TranslucentViewController alloc] init]; self.providesPresentationContextTransitionStyle = YES; self.definesPresentationContext = YES; [tvc setModalPresentationStyle:UIModalPresentationOverCurrentContext]; [self.navigationController presentViewController:tvc animated:YES completion:nil];
fuente
Sé que esta es una pregunta bastante antigua. Estaba atascado en este problema y pude obtener una pista de este hilo. Así que poniendo aquí cómo lo hice funcionar :). Estoy usando un guión gráfico y tengo una transición al ViewController que se va a presentar. El controlador de vista tiene un color de fondo transparente. Ahora, en el inspector de atributos del segue, configuré la presentación en "Sobre el contexto actual". Y funcionó para mí. Estoy desarrollando para iPhone.
fuente
Creé la biblioteca de soruce abierta MZFormSheetController para presentar la hoja de formulario modal en UIWindow adicional. Puede usarlo para presentar el controlador de vista modal de transparencia, incluso ajustar el tamaño del controlador de vista presentado.
fuente
En mi condición, estoy viendo el mismo viewController. Así que cree un nuevo controlador de vista para mantener UIView. Haga que esa vista sea transparente estableciendo su propiedad alfa. Luego, en un botón, haga clic en y escribí este código. Se ve bien.
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];
Y muestra lo que quiero. Espero que ayude a alguien.
fuente
Aquí hay una categoría que he creado que resolverá el problema.
// // UIViewController+Alerts.h // #import <UIKit/UIKit.h> @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
fuente
Después de mucha investigación, parece que esto resolverá nuestro problema y cumplirá nuestro propósito.
cree una transición desde el VC de origen al VC de destino con un identificador.
por ejemplo, "goToDestinationViewController" está bien para facilitar la vida, consideremos el controlador de vista actual, es decir, el que desea detrás de su vista transparente como origen y el destino como destino
Ahora en fuente VC en viewDidLoad: o vista
performSegueWithIdentifier("goToDestinationViewController", sender: nil)
bueno, estamos a mitad de camino. Ahora ve a tu guión gráfico. Haga clic en el segue. que debería verse así: segue
cambie las opciones a lo que se muestra.
Ahora viene la verdadera solución.
en la vista de destino del controlador viewDidLoad agregue este código.
self.modalPresentationStyle = .Custom
.................................................. .......................ASÍ DE FÁCIL......................... .........................................
fuente
self.modalPresentationStyle = .custom
funciona para mí en la presentación modal de un controlador de vista real con un fondo transparente en Swift 3, Xcode 8. El único problema es que si el controlador de vista de presentación está incrustado en un controlador de barra de pestañas, la barra de pestañas aparece frente al transparente vista de fondo.tabBarController.tabBar.isHidden
debe establecerse entrue
.Una forma alternativa es utilizar una "vista de contenedor". Simplemente haga alfa por debajo de 1 e incruste con seque. XCode 5, objetivo iOS7.
no se puede mostrar la imagen, no hay suficiente reputación)))
Vista de contenedor disponible desde iOS6.
fuente
Este código funciona bien en iPhone con iOS6 e iOS7:
presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha' presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext; [presentingVC presentViewController:presentedVC animated:YES completion:NULL];
Pero a lo largo de este camino se pierde la animación de "deslizamiento desde abajo".
fuente
¡Encontré esta solución elegante y simple para iOS 7 y superior!
Para iOS 8, Apple agregó UIModalPresentationOverCurrentContext, pero no funciona para iOS 7 y versiones anteriores, por lo que no pude usarlo para mi caso.
Por favor, cree la categoría y ponga el siguiente código.
archivo .h
typedef void(^DismissBlock)(void); @interface UIViewController (Ext) - (DismissBlock)presentController:(UIViewController *)controller withBackgroundColor:(UIColor *)color andAlpha:(CGFloat)alpha presentCompletion:(void(^)(void))presentCompletion; @end
archivo .m
#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: también funciona para navigationContoller, tabBarController.
Ejemplo de uso:
// 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(); };
¡Disfrútala! y por favor, deja algunos comentarios.
fuente
Esta es la mejor y más limpia forma que encontré hasta ahora:
@protocol EditLoginDelegate <NSObject> - (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]; }
fuente
La mejor solución con la que me he encontrado es utilizar el método addChildViewController. Aquí hay un ejemplo excelente: agregue la vista de un controlador de vista secundaria a una subvista del controlador de vista principal
fuente
Intento usar varios métodos para resolver, pero aún así fallé, el siguiente código se implementó finalmente.
La resolución de Swift:
// A.swift init method modalPresentationStyle = .currentContext // or overCurrentContent modalTransitionStyle = .crossDissolve // dissolve means overlay
luego en el controlador de vista B:
// B.swift let a = A() self.present(a, animated: true, completion: nil)
fuente