19

Tengo un dilema, quiero presentarle al usuario una vista semitransparente.Fondo transparente con un UIViewController modal

Descubrí experimentando que si simplemente empujaba la vista transparente hacia la parte superior de la pila de mi NavigationController, no obtendría el nivel de transparencia que deseaba. Así que decidí simplemente agregar la vista como una subvista de la vista actual en la parte superior de la pila.

Esta solución funciona, la vista siguiente sigue siendo visible, y la vista es 'semi-modal'. El problema es que si la vista principal hereda de UITableViewController (como la mía), la vista que "presiono" sobre ella, no cubre la barra de navegación en la parte superior.

Realmente no quiero entrar en una situación en la que me veo obligado a habilitar/deshabilitar los controles en la barra de navegación cada vez que presiono esta vista, así que me preguntaba si alguien sabía de alguna solución que pudiera usar para que la vista que pulso sobre el UITableViewController en realidad 'presione sobre' la barra de navegación?

+0

http://stackoverflow.com/questions/12741224/ios-modal-viewcontroller-with-transparent-background/22829068#22829068 – Zaraki

Respuesta

13

Es curioso, ayer estaba haciendo lo mismo. Lamentablemente, parece ser imposible. Una vez que el controlador de vista modal está en su lugar, la vista previa se oculta. Vea esto previous question on the topic.

También puede usar el controlador de vista y archivos NIB ha configurado - aquí está mi código de ejemplo

- (void)showUpgrade { 
    [self.upgradeVC viewWillAppear:NO]; 
    [self.view addSubview:self.upgradeVC.view]; 
    [self.upgradeVC viewDidAppear:NO]; 
} 

- (void)hideUpgrade { 
    [self.upgradeVC viewWillDisappear:NO]; 
    [self.upgradeVC.view removeFromSuperview]; 
    [self.upgradeVC viewDidDisappear:NO]; 
} 

- (UpgradeViewController *)upgradeVC { 
    if (_upgradeVC == nil) { 
     _upgradeVC = [[UpgradeViewController alloc] initWithNibName:[NSString stringWithFormat:@"UpgradeView_%@", self.deviceType] bundle:nil]; 
     _upgradeVC.delegate = self; 
    } 
    return _upgradeVC; 
} 

Usted tendrá que almacenar una referencia al controlador de vista de los padres en el controlador de vista modal para que puede acceder al método -hide. Hice esto a través de un delegado.

También sería fácil agregar algo de animación a -show y -hide si desea animarlo desde la parte inferior de la pantalla: era demasiado perezoso para hacer esto.

+0

No creo que apple sdk permita un bg transparente en un UIViewController en el iPhone. –

+0

¿Cómo manejas las diferentes orientaciones del dispositivo cuando haces esto? Me parece que siempre cargará la vista de retrato, que es un problema si la vista actual está en el paisaje. –

+0

esto no es una buena práctica. Mira este artículo. Habla sobre por qué agregar una vista de VC a otra como subvista es una mala idea. http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/ – hackerinheels

-2

¿Ha intentado pasar por encima de las subvistas de la controladora de vista modal y establecer el color de fondo para borrar para cada vista? Esta es una función recursiva de DFS.

- (void)setBackgroundToClearForView:(UIView *)view { 
    if ([view subviews]) { 
     for (UIView *subView in [view subviews]) { 
      [self setBackgroundToClearForView:subView]; 
     } 
    } 

    if ([view respondsToSelector:@selector(setBackgroundColor:)]) { 
     [view performSelector:@selector(setBackgroundColor:) 
        withObject:[UIColor clearColor]]; 
    } 
} 

Para utilizarla llamada:

[self setBackgroundToClearForView:self.view]; 

en viewDidLoad.

+0

No lo intenté yo mismo, pero tengo entendido que la vista principal se ha eliminado de la pila de vista. Ver: http://stackoverflow.com/questions/587681/how-to-use-presentmodalviewcontroller-to-create-a-transparent-view – pix0r

-2

Esto hará el truco .. Pruebe este.

// for clear color or you can easily adjust the alpha here 
YourVC *vc=[[YourVC alloc]initWithNibName:@"YourVC" bundle:nil] ; 
vc.view.backgroundColor = [UIColor clearColor]; 
self.modalPresentationStyle = UIModalPresentationCurrentContext; 
[self presentViewController:vc animated:NO completion:nil]; 

Para que la vista sea a pantalla completa a diferencia de UIModalPresentationFormSheet ..

+3

No funcionó para mí. – mxcl

+1

Esto no funciona, por los motivos descritos: las vistas de fondo se eliminan después de la presentación modal. – tooluser

11

Ahora hay una manera de lograr esto utilizando iOS7 transiciones personalizadas:

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

Para crear su transición a medida, se necesitan 2 cosas:

  • Un objeto TransitionDelegate (aplicación <UIViewControllerTransitionDelegate>)
  • Un objeto "AnimatedTransitioning" (implementando <UIViewControllerAnimatedTransitioning>)

Puede encontrar más información sobre transiciones personalizadas en este tutorial: http://www.doubleencore.com/2013/09/ios-7-custom-transitions/

0

Prueba esto:

ViewController *vc = [[ViewController alloc] init]; 
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext]; 
[self presentViewController:vc animated:YES completion:nil]; 
+0

Lo intenté, no funciona :( – Supertecnoboff

13

iOS 8 añade el UIModalPresentationOverFullScreenpresentation style. Establezca esto como el controlador de vista presentado modalPresentationStyle. Para necesidades más avanzadas, busque crear un presentation controller personalizado.

+0

¡Gracias! Eso funcionó perfectamente para mí :) – Supertecnoboff

+0

Esta debería ser la respuesta correcta ahora que iOS 8+ tiene una adopción de> 91% en dispositivos iOS a partir del 24 de octubre, 2015. – Manuel