UIImagePickerController interrompt l'apparence de la barre d'état

137

Dans mon fichier .plist, j'ai défini " Afficher l'apparence de la barre d'état basée sur le contrôleur " sur NO. Mais après UIImagePickerController, mon application se comporte comme si l'option était définie sur YES.

Dans mon application, je présente un VC qui présente un fichier UIImagePickerController.

Le problème se produit comme ceci:

  • Une fois le sélecteur de photos présenté, lorsqu'une photothèque est sélectionnée, la couleur du texte de la barre d'état change.
  • Puis une fois, UIImagePickerControllerest rejeté, l'espacement de la barre d'état change pour le reste de mon application et toute la barre de navigation pour les autres contrôleurs s'affiche sous la barre d'état.

Existe-t-il un moyen de résoudre ce problème sans gérer la barre d'état dans mes contrôleurs de vue?

Alex L
la source
La réponse dans mon cas était liée aux childviewcontrollers. J'ai dû les recréer au lieu de les réutiliser.
Alex L
7
Cela ressemble vraiment à un bogue iOS 7, est-ce que quelqu'un a déposé un rapport avec Apple?
Dan F
stackoverflow.com/questions/21225978/... question similaire avec la solution simple
Ting Wu
Hé @AlexL, tu sais pourquoi ça arrive?
Shabarinath Pabba

Réponses:

192

Aucune des solutions ci-dessus n'a fonctionné pour moi, mais en combinant les réponses de Rich86man et iOS_DEV_09, j'ai une solution qui fonctionne constamment:

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

et

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

En ce qui concerne cette solution géniale. Pour 2014 / iOS8, j'ai trouvé que dans certains cas, vous devez ÉGALEMENT inclure prefersStatusBarHiddenet, éventuellement, childViewControllerForStatusBarHiddenSo ...

-(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...

J'espère que ça aide quelqu'un

dpjanes
la source
3
Voici l'astuce (comme l'a dit un Rich86man): "Puisque UIImagePickerController est un type de contrôleur de navigation, vous vous définissez également comme délégué UINavigationController."
Beto
2
qu'en est-il après avoir licencié UIImaegPicker ..? J'ai mis la barre d'état cachée à false, puis son arrière-plan devient noir.
Nitin Gohel
Avez-vous le plist configuré selon la question ci-dessus?
dpjanes le
Avez-vous remarqué le problème lors de l'utilisation de UIImagePickerControllerSourceTypePhotoLibrary, de l'ouverture d'un album, puis du recul un peu et de l'annulation du geste?
Kukosk le
3
Cela fonctionne, bien que la barre d'état apparaisse et ressorte d'une manière très saccadée. J'ai déposé un bug avec Apple.
jjxtra
84

J'ai été confronté à ce même problème aujourd'hui. Voici ma solution.

Dans le contrôleur de vue qui appelle le sélecteur d'images, définissez-vous comme délégué du sélecteur d'images. (Vous faites probablement déjà cela)

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

Étant donné que UIImagePickerController est un type de contrôleur de navigation, vous vous définissez également en tant que délégué UINavigationController. Ensuite :

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

Remplacez UIStatusBarStyleLightContent par le style que vous recherchez.

Rich86man
la source
10

La réponse acceptée fonctionnera si vous avez défini `` Afficher l'apparence de la barre d'état basée sur le contrôleur '' sur NON dans votre fichier .plist. Si en effet vous devez contrôler la barre d'état dans certains autres contrôleurs de vue et que cette option est définie sur OUI, l'autre façon de faire en sorte que UIImagePickerController se comporte correctement est de le sous-classer

// .h
@interface MYImagePickerController : UIImagePickerController
@end

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

j'ai fait face au même problème.

voici ma solution. placez-le dans la vue Apparaîtra du contrôleur de vue à partir duquel vous ouvrez la sélection d'image

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

[[UIApplication sharedApplication] setStatusBarHidden:YES];

}
iOS_DEV
la source
4

Pouvez-vous essayer ceci. Je pense que needsStatusBarApperanceUpdate fonctionnera.

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

J'ai trouvé cela pour offrir une bonne manipulation, il y a deux parties.

- (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];
...

le UIImagePickerController lui-même présente les contrôleurs de vue, donc ce délégué fonctionne pour tous les présentateurs de la pile.

viewWillAppear garantit que ce contrôleur de vue lui-même est toujours réinitialisé chaque fois qu'un contrôleur de vue de présentation rejette au-dessus de lui.

Jesse Tayler
la source
3

J'ai eu le même problème. Ajouter dans info plist: "Afficher l'apparence de la barre d'état basée sur le contrôleur" avec la valeur "NON"

Exemple ici https://stackoverflow.com/a/19211669

Cette solution fonctionne pour moi.

serj
la source
2

C'est probablement un bug. J'ai résolu le problème en définissant «Afficher l'apparence de la barre d'état basée sur le contrôleur» sur OUI et dans chaque contrôleur de vue en collant le code suivant:

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Ensuite, mon application se comporte comme prévu.

Jonas
la source
2

Pour masquer la barre d'état dans UIImagePicker:

-

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

et lorsque UIImagePicker est ignoré pour masquer la barre d'état dans le contrôleur View, utilisez le code suivant:

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

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}
Panky
la source
2

essaye ça ....

cela fonctionnera dans les deux cas, à savoir si vous utilisez presentModalViewController et pushViewController

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

déléguer des méthodes

-(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
la source
2

Tout ce qui précède n'a pas fonctionné pour moi. J'ai résolu le problème en modifiant le style de présentation en:

imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
d.ennis
la source
2

Aucune des solutions ci-dessus n'a fonctionné pour moi.

Je présente UIImagePickerController comme contrôleur de vue modale. Après avoir ignoré UIImagePickerController, l'état de la barre d'état était:

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

La solution qui a résolu le problème pour moi était de restaurer statusBarOrientation après avoir ignoré 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
la source
2

Ce code m'a aidé à personnaliser le style de la barre d'état.

EDIT: cette solution fonctionne si "Afficher l'apparence de la barre d'état basée sur le contrôleur" == OUI

@implementation UIImagePickerController (IOS7_StatusBarStyle)

-(UIViewController*)childViewControllerForStatusBarStyle
{
   return nil;
}

-(UIStatusBarStyle)preferredStatusBarStyle
{
   return UIStatusBarStyleLightContent;
}

@end
Igor Palaguta
la source
2

Toutes les réponses ci-dessus sont correctes et peuvent vous aider.

J'ai eu le même problème de devoir gérer l'application exécutée sous différentes versions d'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];

Puis, en délégué:

- (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
la source
2

Encore une autre solution qui peut fonctionner dans certaines situations.

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

Avez-vous essayé d'appeler [self setNeedsStatusBarAppearanceUpdate]lorsque votre contrôleur d'affichage de présentation réapparaît?

Sillon de cendre
la source
C'est probablement un bug alors - je déposerais un radar avec un exemple de projet et je reviendrais à l'ancien système de gestion de la barre d'état :(
Ash Sillon
1

J'essaie de masquer la barre d'état dans UIImagePickerController dans iOS7, mais je ne sais toujours pas comment faire cela. j'utilise

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

dans le ViewController qui appelle le UIImagePickerController et définissez "Afficher l'apparence de la barre d'état basée sur le contrôleur = NON" dans le fichier plist. J'espère que cela peut vous aider.

jxdwinter
la source
1

essaye ça :

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

et dans la mise en œuvre du protocole, utilisez ceci:

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

Cela a résolu le problème pour moi ...:

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

Rien ici n'a spécifiquement résolu le problème en ce que j'avais (et peut-être que l'OP avait aussi), alors j'ai pensé que je partagerais ma réponse. Au lieu de cacher la barre d'état qui, je pense, est une solution buggy (j'ai remarqué qu'elle laissait parfois mon application dans un état où la barre d'état était masquée alors qu'elle ne devrait pas l'être). J'ai plutôt choisi d'essayer de jouer gentiment avec le UIStatusBarStyles.

Lorsque UIImagePickerController a sa vue présentée, je règle le style de la barre d'état par défaut, car la couleur d'arrière-plan par défaut est un gris clair.

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

Ensuite, lorsque le sélecteur d'images est fermé, je le remets au format 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
la source
1

Dans ce cas, nous utilisons 2 étapes

Dans la première étape: ajoutez info.plist: "Afficher l'apparence de la barre d'état basée sur le contrôleur" avec la valeur "NON"

Dans la deuxième étape: utiliser / appeler ce code avec le délégué de UIImagePickerController

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

Dans le cas de l'IOS-7, ajoutez une fonction supplémentaire

- (BOOL)prefersStatusBarHidden
{
    return YES;
}
Vaibhav Sharma
la source
1

Depuis iOS 8.1, il semble qu'ils aient enfin corrigé ce bogue! J'ai pu supprimer toutes les solutions de contournement que j'ai employées de mon code.

Jeff V
la source
1

En utilisant le comportement par défaut d'iOS 8, j'avais des problèmes avec la barre d'état qui apparaissait lorsque je voulais la masquer.

La solution que j'ai trouvée était que, directement après avoir appelé presentPopoverdepuis mon contrôleur de vue, j'ai fait:

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

J'ai également dû ajouter ceci à mon contrôleur de vue principal:

- (UIViewController *)childViewControllerForStatusBarHidden
{
    return nil;
}
JosephH
la source
1

J'ai donc eu ce problème et j'ai pu le résoudre en implémentant simplement une seule fonction de délégué. L'arrière-plan de ma barre d'état est noir, et donc UIStatusBarStyle pour mon application est .LightContent. Lorsque j'ai présenté UIImagePickerController pour sélectionner une photo dans le stockage de l'appareil, la barre d'état était bien. Cependant, en cliquant dans un répertoire tel que "Pellicule" ou "Favoris", poussant effectivement sur la pile de navigation, la barre d'état a disparu. Lors de la sélection d'une photo, il n'y avait pas du tout de barre d'état; lors du rejet d'un autre contrôleur de vue modale, seule la batterie était présente, indiquant que le reste de la barre d'état peut également être noir.

J'ai essayé certaines des autres solutions telles que l'extension de UIImagePickerController, mais dans Swift, vous ne pouvez pas remplacer l'utilisation d'extensions. J'ai ensuite essayé de sous-classer UIImagePickerController et essayé de masquer sa barre d'état sur viewWillAppear () et d'afficher la barre d'état sur viewWillDisappear. J'ai pu voir la barre d'état se cacher avec une animation .Slide, mais comme la barre d'état était invisible lors de la sélection d'un répertoire, je n'ai pas pu voir la barre d'état s'afficher. Encore une fois, la batterie verte est revenue avec le reste de la barre d'état invisible lors du rejet d'un contrôleur de vue modale. J'ai également essayé de remplacer prefersStatusBarHidden (), mais cette fonction n'a jamais été appelée, j'ai donc essayé d'appeler setNeedsStatusBarAppearanceUpdate () pour m'assurer que prefersStatusBarHidden () est appelé par le système, mais il n'est toujours pas appelé. Aussi, il est suggéré de définir la barre d'état à masquer sur la méthode déléguée navigationController willShowViewController. Encore une fois, tout cela ne fait que masquer la barre d'état, ce qui ne résout pas le problème. En fin de compte, il semble que le style de la barre d'état soit modifié lors de la poussée sur la pile de navigation de UIImagePickerController. Pour résoudre entièrement le problème, je n'ai pas eu à écrire d'extensions ou de sous-classe UIImagePickerController. Tout ce que vous avez à faire est de définir le délégué et de définir le style de la barre d'état pour qu'il reste le même. Cet ajout a fait comme si le problème n'avait jamais existé. il semble que le style de la barre d'état soit modifié lors de la poussée sur la pile de navigation de UIImagePickerController. Pour résoudre entièrement le problème, je n'ai pas eu à écrire d'extensions ou de sous-classe UIImagePickerController. Tout ce que vous avez à faire est de définir le délégué et de définir le style de la barre d'état pour qu'il reste le même. Cet ajout a fait comme si le problème n'avait jamais existé. il semble que le style de la barre d'état soit modifié lors de la poussée sur la pile de navigation de UIImagePickerController. Pour résoudre entièrement le problème, je n'ai pas eu à écrire d'extensions ou de sous-classe UIImagePickerController. Tout ce que vous avez à faire est de définir le délégué et de définir le style de la barre d'état pour qu'il reste le même. Cet ajout a fait comme si le problème n'avait jamais existé.

let pickerController = UIImagePickerController()
pickerController.delegate = self

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

En fait, j'ai trouvé un meilleur moyen de définir la couleur d'arrière-plan de la barre d'état dans le sélecteur d'images. Fondamentalement, vous devez définir backgroundImage de la navigationBar sur nil, car la valeur par défaut dans le sélecteur d'images a une backgroundImage en tant qu'image blanche.

André Luiz Alves
la source