UIImagePickerController rompe la apariencia de la barra de estado


137

En mi archivo .plist, tengo " Ver la apariencia de la barra de estado basada en el controlador " configurado en NO. Pero después UIImagePickerController, mi aplicación se comporta como si la opción estuviera establecida en YES.

En mi aplicación, presento un VC que presenta a UIImagePickerController.

El problema ocurre así:

  • Después de que se presenta el selector de fotos, cuando se selecciona una biblioteca de fotos, el color del texto de la barra de estado cambia.
  • Luego, una vez que UIImagePickerControllerse descarta, el espaciado de la barra de estado cambia para el resto de mi aplicación y toda la barra de navegación para otros controladores se muestra debajo de la barra de estado.

¿Hay alguna manera de resolver esto sin administrar la barra de estado en mis controladores de vista?


La respuesta en mi caso estaba vinculada a los controladores childview. Tuve que recrearlos en lugar de reutilizarlos.
Alex L

77
Esto realmente parece un error de iOS 7, ¿alguien ha presentado un informe con Apple?
Dan F

stackoverflow.com/questions/21225978/… pregunta similar con la solución simple
Ting Wu el

Hola @ Alex, ¿sabes por qué sucede?
Shabarinath Pabba

Respuestas:


192

Ninguna de las soluciones anteriores funcionó para mí, pero al combinar las respuestas de Rich86man y iOS_DEV_09, obtuve una solución que funciona constantemente:

UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;

y

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}

En cuanto a esta increíble solución. Para 2014 / iOS8 encontré en algunos casos que TAMBIÉN necesitas incluir prefersStatusBarHiddeny, posiblemente, childViewControllerForStatusBarHiddenEntonces ...

-(void)navigationController:(UINavigationController *)navigationController
        willShowViewController:(UIViewController *)viewController
        animated:(BOOL)animated
    {
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    }

-(BOOL)prefersStatusBarHidden   // iOS8 definitely needs this one. checked.
    {
    return YES;
    }

-(UIViewController *)childViewControllerForStatusBarHidden
    {
    return nil;
    }

-(void)showCamera
    {
    self.cameraController = [[UIImagePickerController alloc] init];
    self.cameraController.delegate = (id)self; // dpjanes solution!
    etc...

Espero que ayude a alguien


3
Este es el truco (como dijo un Rich86man): "Dado que UIImagePickerController es un tipo de controlador de navegación, también se está configurando como el delegado de UINavigationController".
Beto

2
¿Qué pasa después de despedir UIImaegPicker ..? configuré la barra de estado ocultar falso, entonces su fondo se volverá negro.
Nitin Gohel el

¿Tiene el plist configurado según la pregunta anterior?
dpjanes

¿Notó el problema al usar UIImagePickerControllerSourceTypePhotoLibrary, abrir un álbum y luego retroceder un poco y cancelar el gesto?
Kukosk

3
Esto funciona, aunque la barra de estado aparece y se abre de manera muy irregular. He presentado un error con Apple.
jjxtra

84

Me enfrenté a este mismo problema hoy. Aquí está mi solución.

En el controlador de vista que llama al selector de imágenes, configúrate como el delegado del selector de imágenes. (Probablemente ya estés haciendo esto)

UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;

Como UIImagePickerController es un tipo de controlador de navegación, también se está configurando como el delegado de UINavigationController. Luego :

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

Reemplace UIStatusBarStyleLightContent con cualquier estilo que esté buscando.


10

La respuesta aceptada funcionará si tiene la opción 'Ver la apariencia de la barra de estado basada en el controlador' en NO en su archivo .plist. Si realmente necesita controlar la barra de estado en otros controladores de vista y tener esta opción configurada en SÍ, la otra forma de hacer que UIImagePickerController se comporte correctamente es subclasificándola

// .h
@interface MYImagePickerController : UIImagePickerController
@end

// .m
@implementation MYImagePickerController
- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent; // change this to match your style
}
@end

6

Me enfrenté al mismo problema.

Aquí está mi solución. poner esto en la vista Aparecerá del controlador de vista desde el que está abriendo la vista del selector de imágenes

-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];

[[UIApplication sharedApplication] setStatusBarHidden:YES];

}

4

¿Puedes probar esto? Creo que needStatusBarApperanceUpdate funcionará.

1 -Set UIViewControllerBasedStatusBarAppearance to NO.
2- Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
3- [self setNeedsStatusBarAppearanceUpdate];

4

Encontré esto para ofrecer un manejo adecuado, hay dos partes.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
}


- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
...

el UIImagePickerController en sí mismo presenta controladores de vista, por lo que este delegado funciona para todos los presentadores en la pila.

viewWillAppear garantiza que este controlador de vista en sí mismo siempre se restablezca cada vez que un controlador de vista actual se descarta por encima de él.



2

Esto es probablemente un error. Resolví el problema estableciendo "Ver la apariencia de la barra de estado basada en el controlador" en SÍ y en cada controlador de vista pegando el siguiente código:

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Entonces mi aplicación se comporta como se esperaba.


2

Para ocultar la barra de estado en UIImagePicker:

-

 (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

y cuando se descarta UIImagePicker para ocultar la barra de estado en el controlador de vista, use el siguiente código:

-(void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:YES];

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}

2

prueba esto ....

esto funcionará en ambos casos, es decir, si usa presentModalViewController y pushViewController

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;

delegar métodos

-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [picker dismissViewControllerAnimated:YES completion:^{}];
}


- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [picker dismissViewControllerAnimated:YES completion:nil];
}

2

Todo lo anterior no funcionó para mí. Resolví el problema cambiando el estilo de presentación a:

imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;

2

Ninguna de las soluciones anteriores funcionó para mí.

Presento UIImagePickerController como controlador de vista modal. Después de descartar UIImagePickerController, el estado de la barra de estado era:

[UIApplication sharedApplication].statusBarOrientation = 0 (UIDeviceOrientationUnknown)
[UIApplication sharedApplication].statusBarFrame = { 0, 0, 0, 0}

La solución que solucionó el problema para mí fue restaurar statusBarOrientation después de descartar UIImagePickerController:

UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
[self.viewController presentViewController:cameraUI animated:true completion:^(void){ }];

...

[self.viewController dismissViewControllerAnimated:animated completion:^(void){
    [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
}];

2

Este código me ayudó a personalizar el estilo de la barra de estado.

EDITAR: esta solución funciona si "Ver la apariencia de la barra de estado basada en el controlador" == SÍ

@implementation UIImagePickerController (IOS7_StatusBarStyle)

-(UIViewController*)childViewControllerForStatusBarStyle
{
   return nil;
}

-(UIStatusBarStyle)preferredStatusBarStyle
{
   return UIStatusBarStyleLightContent;
}

@end

2

Todas las respuestas anteriores están bien y pueden ayudar.

Tuve el mismo problema al tener que administrar la aplicación ejecutada en diferentes versiones de iOS .

UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];

if(IS_IOS8_AND_UP) {
    imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
} else {
    imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
}

imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];

Luego, en delegado:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    /* Cancel button color  */
    _imagePicker.navigationBar.tintColor = <custom_color>
    /* Status bar color */
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}

2

Otra solución más que puede funcionar en algunas de las situaciones.

let imagePicker =  UIImagePickerController()
imagePicker.sourceType = .PhotoLibrary
imagePicker.navigationBar.barStyle = .Black

1

¿Has intentado llamar [self setNeedsStatusBarAppearanceUpdate]cuando vuelve a aparecer tu controlador de vista actual?


Probablemente sea un error entonces: archivaría un radar con un proyecto de ejemplo y recurriría al antiguo sistema de administración de la barra de estado :(
Ash Furrow

1

Intento ocultar la barra de estado en UIImagePickerController en iOS7, pero todavía no sé cómo hacerlo. yo suelo

- (void)viewWillAppear:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES
                                        withAnimation:UIStatusBarAnimationNone];
}

en el ViewController que llama al UIImagePickerController y establece "Ver apariencia de la barra de estado basada en el controlador = NO" en el archivo plist. Espero que esto pueda ayudar.


1

prueba esto :

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;

y en la implementación del protocolo, use esto:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}

1

Esto lo resolvió para mí ...:

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [picker dismissViewControllerAnimated:YES completion:nil];
}

1

Nada aquí solucionó específicamente el problema que tenía (y tal vez el OP también), así que pensé en compartir mi respuesta. En lugar de ocultar la barra de estado, que creo que es una solución defectuosa (noté que a veces dejaría mi aplicación en un estado donde la barra de estado estaba oculta cuando no debería estarlo). En cambio, opté por tratar de jugar bien con el UIStatusBarStyles.

Cuando se presenta la vista UIImagePickerController, configuro el estilo de la barra de estado como predeterminado, ya que el color de fondo predeterminado es gris claro.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}

Luego, cuando se descarta el selector de imágenes, lo configuro nuevamente en UIStatusBarStyleLightContent.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    //work

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

    [self dismissViewControllerAnimated:YES completion:NULL];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{ 
    //work

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

    [self dismissViewControllerAnimated:YES completion:NULL];
}

1

En este caso, estamos usando 2 pasos

En el primer paso: Agregue info.plist: "Ver la apariencia de la barra de estado basada en el controlador" con el valor "NO"

En el segundo paso: use / llame a este código con el delegado de UIImagePickerController

 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
     if([navigationController isKindOfClass:[UIImagePickerController class]])
         [[UIApplication sharedApplication] setStatusBarHidden:YES]; 
 }

En el caso de IOS-7, agregue una función más

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

1

A partir de iOS 8.1, ¡parece que finalmente han solucionado este error! Pude eliminar todas las soluciones que empleé de mi código.


1

Al usar el comportamiento predeterminado de iOS 8, tenía problemas con la aparición de la barra de estado cuando la quería oculta.

La solución que encontré fue que, directamente después de llamar presentPopoverdesde mi controlador de vista, hice:

    [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate) withObject:nil afterDelay:0.01];

También tuve que agregar esto a mi controlador de vista principal:

- (UIViewController *)childViewControllerForStatusBarHidden
{
    return nil;
}

1

Así que tuve este problema y pude resolverlo simplemente implementando una sola función de delegado. El fondo de mi barra de estado es negro, por lo que UIStatusBarStyle para mi aplicación es .LightContent. Cuando presenté el UIImagePickerController para seleccionar una foto del almacenamiento del dispositivo, la barra de estado estaba bien. Sin embargo, al hacer clic en un directorio como "Camera Roll" o "Favoritos", empujando efectivamente a la pila de navegación, la barra de estado desapareció. Al seleccionar una foto, no había ninguna barra de estado; al descartar otro controlador de vista modal, solo estaba presente la batería, lo que indica que el resto de la barra de estado también puede estar en negro.

Probé algunas de las otras soluciones, como extender UIImagePickerController, pero en Swift, no puede anular el uso de extensiones. Luego intenté subclasificar UIImagePickerController e intenté ocultar su barra de estado en viewWillAppear () y mostrar la barra de estado en viewWillDisappear. Pude ver que la barra de estado se ocultaba con una animación .Slide, pero como la barra de estado era invisible al seleccionar un directorio, no pude ver la barra de estado oculta. Nuevamente, la batería verde volvió con el resto de la barra de estado invisible al descartar un controlador de vista modal. También intenté anular prefersStatusBarHidden (), pero esa función nunca se llamó, por lo que intenté llamar a setNeedsStatusBarAppearanceUpdate () para asegurarme de que el sistema llama a prefersStatusBarHidden (), pero todavía no se llama. También, existe la sugerencia de configurar la barra de estado para que se oculte en el método de delegado navigationController willShowViewController. Una vez más, todo lo que hace es ocultar la barra de estado, que no resuelve el problema. Como resultado, parece que el estilo de la barra de estado cambia al presionar sobre la pila de navegación del UIImagePickerController. Para resolver el problema por completo, no tuve que escribir extensiones o subclase UIImagePickerController. Todo lo que necesita hacer es configurar el delegado y configurar el estilo de la barra de estado para que permanezca igual. Esta adición hizo que el problema nunca existiera. parece que el estilo de la barra de estado cambia al presionar sobre la pila de navegación del UIImagePickerController. Para resolver el problema por completo, no tuve que escribir extensiones o subclase UIImagePickerController. Todo lo que necesita hacer es configurar el delegado y configurar el estilo de la barra de estado para que permanezca igual. Esta adición hizo que el problema nunca existiera. parece que el estilo de la barra de estado cambia al presionar sobre la pila de navegación del UIImagePickerController. Para resolver el problema por completo, no tuve que escribir extensiones o subclase UIImagePickerController. Todo lo que necesita hacer es configurar el delegado y configurar el estilo de la barra de estado para que permanezca igual. Esta adición hizo que el problema nunca existiera.

let pickerController = UIImagePickerController()
pickerController.delegate = self

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
        UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: false)
    }

-1

En realidad, encontré una mejor manera de configurar el color de fondo de la barra de estado en el Selector de imágenes. Básicamente, debe establecer la imagen de fondo de la barra de navegación en nula, porque el valor predeterminado en el selector de imágenes tiene una imagen de fondo como una imagen blanca.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.