iphone - objective - Muestra clearColor UIViewController sobre UIViewController
navigation controller objective c (16)
Tengo una vista UIViewController
como subvista / modal en la parte superior de otra vista de UIViewController
, como que la subvista / modal debe ser transparente y los componentes que se agreguen a la subvista deberían estar visibles. El problema es que tengo que la subvista muestra fondo negro para tener clearColor. Estoy tratando de hacer que UIView
un color claro, no negro. ¿Alguien sabe lo que está mal con eso? Cualquier sugerencia apreciada.
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];
}
RESUELTO : arreglé los problemas. Está funcionando muy bien tanto para iPhone como para iPad. Controlador de vista modal sin fondo negro solo clearColor / transparent. Lo único que tengo que cambiar es reemplazar UIModalPresentationFullScreen
a UIModalPresentationCurrentContext
. ¡Qué simple es eso!
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];
AVISO: si está utilizando una propiedad modalPresentationStyle
de 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];
AVISO: La mala noticia es que la solución anterior no funciona en iOS 7. ¡La buena noticia es que arreglé el problema para iOS7! Le pedí ayuda a alguien y aquí está lo que dijo:
Al presentar un controlador de vista modalmente, iOS quita los controladores de vista debajo de él de la jerarquía de vista por la duración que se presenta. Si bien la vista de su controlador de vista presentado de forma modal es transparente, no hay nada debajo excepto la ventana de la aplicación, que es negra. iOS 7 introdujo un nuevo estilo de presentación modal, UIModalPresentationCustom
, que hace que iOS no elimine las vistas debajo del controlador de vista presentado. Sin embargo, para usar este estilo de presentación modal, debe proporcionar su propio delegado de transición para manejar la presentación y descartar las animaciones. Esto se describe en la charla ''Transiciones personalizadas usando controladores de vista'' desde WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 que también cubre cómo implementar su propio delegado de transición.
Puede ver mi solución para el problema anterior en iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions
Para iOS7
Ahora hay una forma de lograr esto usando las transiciones personalizadas de iOS7, de esta manera:
MyController * controller = [MyController new];
[controller setTransitioningDelegate:self.transitionController];
controller.modalPresentationStyle = UIModalPresentationCustom;
[self controller animated:YES completion:nil];
Para crear su transición personalizada, necesita 2 cosas:
- Un objeto TransitionDelegate (implementando
<UIViewControllerTransitionDelegate>
) - Un objeto "AnimatedTransitioning" (implementando
<UIViewControllerAnimatedTransitioning>
)
Puede encontrar más información sobre transiciones personalizadas en este tutorial .
Encontré que la forma más fácil de hacerlo funcionar en iOS7 y iOS8 es agregar establecer el estilo de presentación a UIModalPresentationOverCurrentContext en modallyPresentedVC (ViewController, que desea presentar modalmente) debido a iOS8:
[modallyPresentedVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[modallyPresentedVC.navigationController setModalPresentationStyle:UIModalPresentationOverCurrentContext];
y UIModalPresentationCurrentContext en la presentación de VC (el controlador que presenta modallyPresented) debido a iOS7:
[presentingVC setModalPresentationStyle:UIModalPresentationCurrentContext];
[presentingVC.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];
Porque las cosas se manejan de manera diferente en iOS7 e iOS8. Por supuesto, no tiene que establecer las propiedades de navigationController si no está utilizando una. Espero que ayude.
Entonces, para los pensadores puramente visuales y los fanáticos del guión gráfico, puedes hacer:
1. Presentación del controlador de vista
2. Controlador de vista presentado
No he jugado mucho con el constructor Storyboard / Interface, pero lo que me llama la atención es que estás diciendo que la vista es de color claro (es decir, 100% alfa / transparente) y también que es opaca ( 0% alfa - completamente sólido). Estas dos cosas no parecen encajar. Yo comentaría el self.view.opaque = YES;
línea y ver si funciona entonces;)
Ah, otra cosa en la que acabo de pensar: es muy posible que tu controlador de vista TENGA el fondo alfa, pero por supuesto el alfa se mostrará al color de la ventana base o controlador de vista raíz del programa, que es por negro predeterminado. La capa básica de toda tu aplicación no puede tener un fondo transparente, ¿transparente para qué? ¿Qué hay detrás? Tiene que haber algo que ver A TRAVÉS de la transparencia. ¿Tiene sentido?
Otra forma (no es necesario crear una transición personalizada y funciona en iOS 7)
Usando Storyboard:
Cree el Controlador de vista infantil con el tamaño de libertad, establezca el ancho de vista en 500x500 (por ejemplo) y agregue el siguiente método:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.view.superview.bounds = CGRectMake(0, 0, 500, 500);
self.view.superview.backgroundColor = [UIColor clearColor];
}
Luego crea una transición modal con Hoja de formulario y pruébala.
Para Mí, esto funciona:
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
es el controlador de la Vista transparente y también he hecho que el MMPushNotificationViewController
de la vista de MMPushNotificationViewController sea de color claro. Ahora todo lo que he hecho y hecho mi Transparentviewcontroller.
Para iOS 7 y solo con Interface Builder, se puede lograr estableciendo la Presentación en "Over Current Context" en todos los controladores de vista involucrados en la presentación modal. Incluso para los controladores de navegación.
Por ejemplo, configúrelo en todos estos controladores de vista:
NavController -> RootViewController -> ModalViewController
Solo use "self.modalPresentationStyle = UIModalPresentationCurrentContext;", al presentar la vista
Funcionará bien :)
Solución Swift 3 y 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)
Solución iOS 7 con segue personalizado:
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
Solución basada en el código de alta tecnología.
También puede ''volver a agregar'' la ventana a la 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];
Y de esta manera, la presentación puede ser animada.
Versión 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)
Funciona muy bien en iOS7 e iOS8
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];
RESUELTO : arreglé los problemas. Está funcionando muy bien tanto para iPhone como para iPad. Controlador de vista modal sin fondo negro solo clearColor / transparent. Lo único que tengo que cambiar es reemplazar UIModalPresentationFullScreen a UIModalPresentationCurrentContext. ¡Qué simple es eso!
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];
AVISO: si está utilizando una propiedad modalPresentationStyle de 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];
AVISO: La mala noticia es que la solución anterior no funciona en iOS 7. ¡La buena noticia es que arreglé el problema para iOS7! Le pedí ayuda a alguien y aquí está lo que dijo:
Al presentar un controlador de vista modalmente, iOS quita los controladores de vista debajo de él de la jerarquía de vista por la duración que se presenta. Si bien la vista de su controlador de vista presentado de forma modal es transparente, no hay nada debajo excepto la ventana de la aplicación, que es negra. iOS 7 introdujo un nuevo estilo de presentación modal, UIModalPresentationCustom, que hace que iOS no elimine las vistas debajo del controlador de vista presentado. Sin embargo, para usar este estilo de presentación modal, debe proporcionar su propio delegado de transición para manejar la presentación y descartar las animaciones. Esto se describe en la charla ''Transiciones personalizadas usando controladores de vista'' desde WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 que también cubre cómo implementar su propio delegado de transición.
Puede ver mi solución para el problema anterior en iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions
iOS8 +
En iOS8 + ahora puede usar el nuevo modalPresentationStyle UIModalPresentationOverCurrentContext para presentar un controlador de vista con un fondo transparente:
MyModalViewController *modalViewController = [[MyModalViewController alloc] init];
modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:modalViewController animated:YES completion:nil];