iphone - precio - Cómo usar presentModalViewController para crear una vista transparente
iphone xr (20)
¡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 anteriores, por lo que no pude usarlo para mi caso.
Por favor, crea la categoría y pon 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.
Estoy mostrando una vista modal con
[self presentModalViewController:controller animated:YES];
Cuando la vista se mueve hacia arriba de la pantalla, es transparente según la configuración en el archivo xib desde el que se crea, pero una vez que llena la pantalla, se vuelve opaca.
¿Hay alguna forma de mantener la vista transparente?
Sospecho que la vista que se está colocando no se está procesando, sino que la vista modal se está volviendo opaca.
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
Después de iOS 3.2, hay un método para hacerlo sin ningún "truco": consulte la documentación de la propiedad modalPresentationStyle . Usted tiene un controlador raízViewController que presentará viewController. Así que aquí está el código para el éxito:
viewController.view.backgroundColor = [UIColor clearColor];
rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
[rootViewController presentModalViewController:viewController animated:YES];
Con este método, el fondo del 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.
Después de una gran cantidad de investigaciones, esto resolverá nuestro problema y servirá para nuestro propósito.
crear una transición del 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 fuente y el destino como destino
Ahora en fuente VC en viewDidLoad: o vista
performSegueWithIdentifier("goToDestinationViewController", sender: nil)
bueno, estamos a la mitad. 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 viewDidLoad del controlador de vista de destino agrega este código.
self.modalPresentationStyle = .Custom
.................................................. .......................ASÍ DE FÁCIL......................... .........................................
En mi condición, tengo vista en el mismo viewController. Así que crea un nuevo controlador de vista para guardar UIView. Haga que la vista sea transparente estableciendo su propiedad alfa. Luego, al hacer clic en un botón, 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.
Escribí mis hallazgos sobre esto en una pregunta diferente , pero la esencia es que tienes que llamar a modalPresentationStyle = UIModalPresentationCurrentContext
en lo que sea que posea la pantalla completa en este momento. La mayoría de las veces, es lo que sea la [aplicación compartida UIApplication] .delegate.window''s rootViewController. También podría ser un nuevo UIViewController que se presentó con modalPresentationStyle = UIModalPresentationFullScreen
.
Por favor, lea mi otra publicación mucho más detallada si se pregunta cómo he resuelto específicamente este problema. ¡Buena suerte!
Esta es la mejor y más limpia forma que he encontrado 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];
}
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 pierdes la animación de "desliza desde abajo".
Esto funcionó para mí en iOS 8-9:
1- Configure el fondo de su 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];
Esto parece estar roto en IOS 8, estoy usando un controlador de navegación y el contexto que se muestra es el contexto de menús de navegación, que en nuestro caso es un controlador de menú deslizante.
Estamos utilizando el pod ''TWTSideMenuViewController'', ''0.3'' no se ha comprobado para ver si este es un problema con la biblioteca o el método descrito anteriormente.
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 la imagen a la vista del controlador que está a punto de mostrar. Luego envíe para volver. Inserte otra vista encima de la vista de la imagen (fondo negro, alfa 0.7). Muestre su controlador modal y parece que fue transparente. Acabo de probarlo en el iPhone 4 con iOS 4.3.1. Como encanto.
La forma aprobada por Apple para hacer esto en iOS 8 es establecer el modalPresentationStyle en ''UIModalPresentationOverCurrentContext''.
De la documentación de UIViewController:
UIModalPresentationOverCurrentContext
Un estilo de presentación donde el contenido se muestra solo sobre el contenido del controlador de vista padre. Las vistas debajo del contenido presentado no se eliminan de la jerarquía de vistas cuando finaliza la presentación. Entonces, si el controlador de vista presentado no llena la pantalla con contenido opaco, el contenido subyacente se muestra a través de.
Al presentar un controlador de vista en un popover, este estilo de presentación solo se admite si el estilo de transición es UIModalTransitionStyleCoverVertical. Intentar utilizar un estilo de transición diferente desencadena una excepción. Sin embargo, puede usar otros estilos de transición (excepto la transición de curvatura parcial) si el controlador de vista principal no está en un popover.
Disponible en iOS 8.0 y posterior.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/
El video ''Ver mejoras del controlador en iOS 8'' de la WWDC 2014 entra en esto con cierto detalle.
Asegúrese de dar a su controlador de vista presentado un color de fondo claro (de lo contrario, todavía aparecerá opaco).
La mejor solución que he encontrado es usar el método addChildViewController. Este es un excelente ejemplo: agregue una vista de controlador de vista secundaria a una subvista del controlador de vista principal
Lo que necesitaba para que esto funcione:
self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
Otra forma es usar una "vista de contenedor". Simplemente haz alfa debajo de 1 e incrusta con seque. XCode 5, objetivo iOS7.
no se puede mostrar la imagen, no hay suficiente reputación)))
Vista de contenedor disponible desde iOS6.
Para aquellos que quieren ver algún 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];
}
Sé que esta es una pregunta bastante antigua. Estaba atascado en este tema y pude obtener una pista de este hilo. Así que poner aquí cómo lo hice funcionó :). Estoy usando el guión gráfico y he seguido el 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.
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 ella está oculta (como es el caso con cualquier controlador de vista superior). La solución es animar manualmente una vista usted mismo; entonces el behind-viewController no estará oculto (ya que no lo habrá "dejado").
esto es bastante antiguo, pero resolví el mismo problema de la siguiente manera: dado que necesito presentar un controlador de navegación en iPhone, agregar una subvista no era una solución viable.
Entonces, ¿qué 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 subvista, enviándolo a atrás.
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 (utilicé 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!
MZFormSheetController biblioteca de MZFormSheetController 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.