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?

Alex L
fuente
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

dpjanes
fuente
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.

Rich86man
fuente
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
mgcm
fuente
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];

}
iOS_DEV
fuente
4

¿Puedes probar esto? Creo que needStatusBarApperanceUpdate funcionará.

1 -Set UIViewControllerBasedStatusBarAppearance to NO.
2- Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
3- [self setNeedsStatusBarAppearanceUpdate];
Burcu Geneci
fuente
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.

Jesse Tayler
fuente
3

Yo tuve el mismo problema. Añadir información plist: "Ver la apariencia de la barra de estado basada en el controlador" con el valor "NO"

Ejemplo aquí https://stackoverflow.com/a/19211669

Esta solución me funciona.

serj
fuente
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.

Jonas
fuente
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];

}
Panky
fuente
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];
}
Shaik Riyaz
fuente
2

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

imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
d.ennis
fuente
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;
}];
Mihail Varbanov
fuente
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
Igor Palaguta
fuente
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];
}
Luca Davanzo
fuente
2

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

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

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

Surco de ceniza
fuente
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.

jxdwinter
fuente
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];
}
ouyongyong
fuente
1

Esto lo resolvió para mí ...:

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [picker dismissViewControllerAnimated:YES completion:nil];
}
Seb OH
fuente
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];
}
Ian Hoar
fuente
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;
}
Vaibhav Sharma
fuente
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.

Jeff V
fuente
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;
}
JosephH
fuente
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)
    }
SwiftMatt
fuente
-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.

André Luiz Alves
fuente