web-dev-qa-db-fra.com

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

Dans mon fichier .plist, j'ai "Apparence de la barre d'état basée sur le contrôleur d'affichage" 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 UIImagePickerController.

Le problème se passe comme ça:

  • Une fois le sélecteur de photos présenté, lorsqu'une bibliothèque de photos est sélectionnée, la couleur du texte de la barre d'état change.
  • Ensuite, une fois, UIImagePickerController est renvoyé, l'espacement des barres d'état change pour le reste de mon application et toute la barre de navigation des 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 les contrôleurs de vue?

137
Alex L

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 de manière constante:

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é dans certains cas que vous deviez également inclure prefersStatusBarHidden et éventuellement childViewControllerForStatusBarHidden Donc ...

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

192
dpjanes

J'ai fait face au 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 en tant que délégué du sélecteur d'images. (Vous êtes probablement déjà en train de le faire)

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

UIImagePickerController étant 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.

84
Rich86man

La réponse acceptée fonctionnera si vous avez l'option 'Afficher l'apparence de la barre d'état basée sur le contrôleur' ​​définie sur NO dans votre fichier .plist. Si vous avez effectivement besoin de contrôler la barre d'état dans d'autres contrôleurs de vue et que cette option est définie sur YES, l'autre méthode permettant à UIImagePickerController de se comporter correctement consiste à la sous-classer.

// .h
@interface MYImagePickerController : UIImagePickerController
@end

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

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

voici ma solution. mettre ceci dans la vueWillAppear 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];

}
6
iOS_DEV

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

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

J'ai trouvé cela pour offrir une manipulation appropriée, 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];
...

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

viewWillAppear garantit que ce contrôleur de vue est toujours réinitialisé chaque fois qu'un contrôleur de vue présentateur le refuse.

4
Jesse Tayler

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

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

Cette solution fonctionne pour moi.

3
serj

Encore une autre solution qui peut fonctionner dans certaines situations.

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

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

EDIT: cette solution fonctionne si "Voir 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
2
Igor Palaguta

C'est probablement un bug. J'ai résolu le problème en définissant "Apparence de la barre d'état basée sur le contrôleur de vue" sur OUI et à chaque collage de contrôleur de vue dans le code suivant:

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Ensuite, mon application se comporte comme prévu.

2
Jonas

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 congédié pour masquer la barre d'état dans View controller, utilisez le code suivant:

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

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}
2
Panky

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

Je présente UIImagePickerController en tant que contrôleur de vue modal. Après avoir rejeté UIImagePickerController, l'état de la barre d'état était le suivant:

[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 rejeté 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
Mihail Varbanov

essaye ça ....

cela fonctionnera dans les deux cas, que vous utilisiez presentModalViewController ou pushViewController.

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

méthodes déléguées

-(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
Shaik Riyaz

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

J'ai eu le même problème devant 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];

Ensuite, 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];
}
2
Luca Davanzo

Dans ce cas, nous utilisons 2 étapes

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

En seconde étape: Utilisez/appelez 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 d'IOS-7, ajoutez une fonction supplémentaire

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

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

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

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;
1
d.ennis

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

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

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

1
jxdwinter

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

La solution que j’ai trouvée est que, immédiatement après avoir appelé presentPopover depuis 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 principale:

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

Rien ici ne résout spécifiquement le problème que je rencontrais (et peut-être que le PO en avait aussi), alors j'ai pensé partager ma réponse. Au lieu de masquer la barre d'état, ce qui me semble une solution problématique (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 à Nice avec le UIStatusBarStyles.

Lorsque la vue de UIImagePickerController est présentée, je règle le style de 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’image est désactivé, je le remets dans la position 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
Ian Hoar

Depuis iOS 8.1, il semble qu'ils aient enfin résolu ce problème! J'ai pu supprimer toutes les solutions de contournement que j'ai utilisées de mon code.

1
Jeff V

Avez-vous essayé d'appeler [self setNeedsStatusBarAppearanceUpdate] lorsque votre contrôleur de présentation s'affiche à nouveau?

1
Ash Furrow

J'ai donc eu ce problème et j'ai pu le résoudre simplement en implémentant une fonction de délégué unique. L'arrière-plan de ma barre d'état est noir et UIStatusBarStyle pour mon application est donc .LightContent. Lorsque j'ai présenté UIImagePickerController pour sélectionner une photo dans le stockage du périphérique, la barre d'état était correcte. Cependant, lorsque vous cliquez dans un répertoire tel que "Pellicule" ou "Favoris", en appuyant sur la pile de navigation, la barre d'état disparaît. Lors de la sélection d'une photo, il n'y avait pas de barre d'état du tout; en quittant un autre contrôleur de vue modale, seule la batterie était présente, ce qui indique que le reste de la barre d'état peut également être noir.

J'ai essayé d'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 de masquer la barre d'état sur viewWillDisappear. J'ai pu voir la barre d'état se masquer avec une animation .Slide, mais comme la barre d'état était invisible lors de la sélection d'un répertoire, je ne pouvais pas voir la barre d'état se masquer. Encore une fois, la batterie verte est revenue avec le reste de la barre d'état invisible après avoir congédié un contrôleur de vue modale. J'ai également essayé de surcharger 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 ce n'est toujours pas appelé. En outre, il est suggéré de définir le masquage de la barre d'état sur la méthode déléguée navigationController willShowViewController. Encore une fois, tout cela est masqué la barre d’état, ce qui ne résout pas le problème. Il se trouve que le style de la barre d’état est modifié lorsqu’on appuie 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-classes 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 identique. Cet ajout l'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)
    }
1
SwiftMatt

essaye ça :

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

et dans l'implémentation du protocole, utilisez ceci:

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