UIImagePickerController unterbricht das Erscheinungsbild der Statusleiste

137

In meiner .plist-Datei ist "Erscheinungsbild der Controller-basierten Statusleiste anzeigen " eingestellt NO. Aber danach UIImagePickerControllerverhält sich meine App so, als ob die Option auf gesetzt wäre YES.

In meiner App präsentiere ich eine VC, die eine präsentiert UIImagePickerController.

Das Problem passiert folgendermaßen:

  • Nach der Präsentation der Fotoauswahl ändert sich beim Auswählen einer Fotobibliothek die Farbe des Textes in der Statusleiste.
  • Sobald dies beendet UIImagePickerControllerist, ändert sich der Abstand der Statusleiste für den Rest meiner App und die gesamte Navigationsleiste für andere Controller wird unter der Statusleiste angezeigt.

Gibt es eine Möglichkeit, dies zu lösen, ohne die Statusleiste in meinen View Controllern zu verwalten?

Alex L.
quelle
Die Antwort in meinem Fall war an Childviewcontroller gebunden. Ich musste sie neu erstellen, anstatt sie wiederzuverwenden.
Alex L
7
Dies scheint wirklich ein iOS 7-Fehler zu sein. Hat jemand einen Bericht bei Apple eingereicht?
Dan F
stackoverflow.com/questions/21225978/… ähnliche Frage mit der einfachen Lösung
Ting Wu
Hey @AlexL, weißt du warum es passiert?
Shabarinath Pabba

Antworten:

192

Keine der oben genannten Lösungen hat bei mir funktioniert, aber durch die Kombination der Antworten von Rich86man und iOS_DEV_09 habe ich eine konsistent funktionierende Lösung:

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

und

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

In Bezug auf diese tolle Lösung. Für 2014 / iOS8 habe ich in einigen Fällen festgestellt, dass Sie AUCH einschließen müssen prefersStatusBarHiddenund möglicherweise childViewControllerForStatusBarHidden...

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

Hoffe es hilft jemandem

dpjanes
quelle
3
Dies ist der Trick (wie ein Rich86man sagte): "Da UIImagePickerController eine Art Navigationscontroller ist, setzen Sie sich auch als UINavigationController-Delegat."
Beto
2
was ist nach der Entlassung von UIImaegPicker ..? Ich setze Statusleiste verstecken falsch, dann wird der Hintergrund schwarz.
Nitin Gohel
Haben Sie die Liste gemäß der obigen Frage eingerichtet?
dpjanes
Haben Sie das Problem bemerkt, als Sie UIImagePickerControllerSourceTypePhotoLibrary verwendeten, ein Album öffneten, ein wenig zurückschwenkten und die Geste abbrachen?
Kukosk
3
Dies funktioniert, obwohl die Statusleiste sehr ruckartig ein- und ausgeblendet wird. Ich habe einen Fehler bei Apple gemeldet.
jjxtra
84

Ich stand heute vor dem gleichen Problem. Hier ist meine Lösung.

Legen Sie sich im Ansichtscontroller, der die Bildauswahl aufruft, als Delegat der Bildauswahl fest. (Du machst das wahrscheinlich schon)

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

Da UIImagePickerController eine Art Navigationscontroller ist, legen Sie sich auch als UINavigationController-Delegat fest. Dann :

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

Ersetzen Sie UIStatusBarStyleLightContent durch den gewünschten Stil.

Rich86man
quelle
10

Die akzeptierte Antwort funktioniert, wenn Sie in Ihrer .plist-Datei die Option "Controller-basiertes Statusleisten-Erscheinungsbild anzeigen" auf NEIN gesetzt haben. Wenn Sie in der Tat die Statusleiste in einigen anderen Ansichtscontrollern steuern und diese Option auf JA setzen müssen, können Sie UIImagePickerController auf andere Weise korrekt verhalten, indem Sie sie in Unterklassen unterteilen

// .h
@interface MYImagePickerController : UIImagePickerController
@end

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

Ich stand vor dem gleichen Problem.

Hier ist meine Lösung. Fügen Sie dies in viewWillAppear des View Controllers ein, von dem aus Sie die Bildauswahlansicht öffnen

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

[[UIApplication sharedApplication] setStatusBarHidden:YES];

}
iOS_DEV
quelle
4

Kannst du das versuchen? Ich denke, brauchtStatusBarApperanceUpdate wird funktionieren.

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

Ich fand, dass dies eine ordnungsgemäße Handhabung bietet. Es gibt zwei Teile.

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

Der UIImagePickerController selbst präsentiert Ansichtscontroller, sodass dieser Delegat für alle Präsentatoren auf dem Stapel funktioniert.

Der viewWillAppear stellt sicher, dass dieser Ansichts-Controller selbst immer zurückgesetzt wird, wenn ein präsentierender Ansichts-Controller darüber geschlossen wird.

Jesse Tayler
quelle
3

Ich hatte das gleiche Problem. Info-Liste hinzufügen: "Aussehen der Controller-basierten Statusleiste anzeigen" mit dem Wert "NEIN"

Beispiel hier https://stackoverflow.com/a/19211669

Diese Lösung funktioniert bei mir.

serj
quelle
2

Dies ist wahrscheinlich ein Fehler. Ich habe das Problem gelöst, indem ich "View Controller-based Status Bar Erscheinungsbild" auf YES gesetzt und in jedem View Controller den folgenden Code eingefügt habe:

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Dann verhält sich meine App wie erwartet.

Jonas
quelle
2

Zum Ausblenden der Statusleiste in UIImagePicker:

- -

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

Wenn UIImagePicker geschlossen wird, um die Statusleiste im View Controller auszublenden, verwenden Sie den folgenden Code:

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

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}
Panky
quelle
2

Versuche dies ....

Dies funktioniert in beiden Fällen, dh ob Sie presentModalViewController und pushViewController verwenden

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

Methoden delegieren

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

All das hat bei mir nicht funktioniert. Ich habe das Problem gelöst, indem ich den Präsentationsstil geändert habe in:

imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
d.ennis
quelle
2

Keine der oben genannten Lösungen hat bei mir funktioniert.

Ich präsentiere UIImagePickerController als Modal View Controller. Nach dem Schließen von UIImagePickerController lautete der Statusleistenstatus:

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

Die Lösung, die das Problem für mich behoben hat, war die Wiederherstellung von statusBarOrientation nach dem Schließen von 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
quelle
2

Dieser Code hat mir geholfen, den Stil der Statusleiste anzupassen.

BEARBEITEN: Diese Lösung funktioniert, wenn "Controller-basiertes Statusleisten-Erscheinungsbild anzeigen" == JA

@implementation UIImagePickerController (IOS7_StatusBarStyle)

-(UIViewController*)childViewControllerForStatusBarStyle
{
   return nil;
}

-(UIStatusBarStyle)preferredStatusBarStyle
{
   return UIStatusBarStyleLightContent;
}

@end
Igor Palaguta
quelle
2

Alle obigen Antworten sind in Ordnung und können helfen.

Ich hatte das gleiche Problem mit der Verwaltung der Anwendung, die unter verschiedenen iOS-Versionen ausgeführt wurde .

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

Dann im Delegierten:

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

Noch eine andere Lösung, die in einigen Situationen funktionieren kann.

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

Haben Sie versucht anzurufen, [self setNeedsStatusBarAppearanceUpdate]wenn Ihr Präsentations-View-Controller wieder angezeigt wird?

Eschenfurche
quelle
Dann ist es wahrscheinlich ein Fehler - ich würde ein Radar mit einem Beispielprojekt einreichen und auf das alte System zur Verwaltung der Statusleiste zurückgreifen :(
Ash Furrow
1

Ich versuche, die Statusleiste in UIImagePickerController in iOS7 auszublenden, weiß aber immer noch nicht, wie das geht. ich benutze

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

im ViewController, der den UIImagePickerController aufruft, und setzen Sie in der plist-Datei "View controller-based status bar display = NO". Hoffe das kann helfen.

jxdwinter
quelle
1

Versuche dies :

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

Verwenden Sie im Protokollimplement Folgendes:

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

Das hat es für mich gelöst ...:

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

Nichts hier hat das Problem speziell behoben, das ich hatte (und vielleicht auch das OP), also dachte ich, ich würde meine Antwort teilen. Anstatt die Statusleiste auszublenden, was ich für eine fehlerhafte Lösung halte (ich bemerkte, dass meine App manchmal in einem Zustand belassen wurde, in dem die Statusleiste ausgeblendet war, wenn dies nicht der Fall sein sollte). Ich habe mich stattdessen dafür entschieden, nett mit dem zu spielenUIStatusBarStyles .

Wenn die Ansicht des UIImagePickerControllers angezeigt wird, habe ich den Statusleistenstil auf Standard gesetzt, da die Standardhintergrundfarbe hellgrau ist.

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

Wenn der Bildwähler dann geschlossen wird, setze ich ihn wieder auf 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
quelle
1

In diesem Fall verwenden wir 2 Schritte

Im ersten Schritt: In info.plist hinzufügen: "Controller-basiertes Statusleisten-Erscheinungsbild anzeigen" mit dem Wert "NO"

Im zweiten Schritt: Verwenden / Aufrufen dieses Codes mit dem Delegaten von UIImagePickerController

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

Im Falle von IOS-7 fügen Sie eine weitere Funktion hinzu

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

Ab iOS 8.1 scheinen sie diesen Fehler endlich behoben zu haben! Ich konnte alle von mir verwendeten Problemumgehungen aus meinem Code entfernen.

Jeff V.
quelle
1

Bei Verwendung des Standardverhaltens von iOS 8 hatte ich Probleme mit der Statusleiste, die angezeigt wurde, als ich sie ausblenden wollte.

Die Lösung, die ich fand, war, dass ich direkt nach dem Aufruf presentPopovervon meinem View Controller Folgendes tat:

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

Ich musste dies auch meinem Hauptansichts-Controller hinzufügen:

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

Ich hatte dieses Problem und konnte es lösen, indem ich einfach eine einzelne Delegatenfunktion implementierte. Der Hintergrund meiner Statusleiste ist schwarz, daher lautet UIStatusBarStyle für meine Anwendung .LightContent. Als ich den UIImagePickerController vorstellte, um ein Foto aus dem Gerätespeicher auszuwählen, war die Statusleiste in Ordnung. Beim Klicken in ein Verzeichnis wie "Kamerarolle" oder "Favoriten", das effektiv auf den Navigationsstapel verschoben wurde, verschwand die Statusleiste. Bei der Auswahl eines Fotos gab es überhaupt keine Statusleiste. Beim Entfernen eines anderen Modal View Controllers war nur die Batterie vorhanden, was darauf hinweist, dass der Rest der Statusleiste möglicherweise ebenfalls schwarz ist.

Ich habe einige der anderen Lösungen ausprobiert, z. B. die Erweiterung von UIImagePickerController, aber in Swift können Sie die Verwendung von Erweiterungen nicht überschreiben. Ich habe dann versucht, UIImagePickerController in eine Unterklasse zu unterteilen, die Statusleiste in viewWillAppear () auszublenden und die Statusleiste in viewWillDisappear auszublenden. Ich konnte sehen, wie die Statusleiste mit einer .Slide-Animation ausgeblendet wurde, aber da die Statusleiste bei Auswahl eines Verzeichnisses unsichtbar war, konnte ich die Statusleiste nicht einblenden sehen. Wieder kam die grüne Batterie mit dem Rest der Statusleiste zurück, der beim Entlassen eines Modal View Controllers unsichtbar war. Ich habe auch versucht, prefersStatusBarHidden () zu überschreiben, aber diese Funktion wurde nie aufgerufen. Deshalb habe ich versucht, setNeedsStatusBarAppearanceUpdate () aufzurufen, um sicherzustellen, dass prefersStatusBarHidden () vom System aufgerufen wird, aber immer noch nicht aufgerufen wird. Ebenfalls, Es gibt den Vorschlag, die Statusleiste so einzustellen, dass sie in der Delegatmethode navigationController willShowViewController ausgeblendet wird. Dies bedeutet wiederum nur, dass die Statusleiste ausgeblendet wird, wodurch das Problem nicht gelöst wird. Wie sich herausstellt, scheint sich der Stil der Statusleiste beim Drücken auf den Navigationsstapel des UIImagePickerController zu ändern. Um das Problem vollständig zu lösen, musste ich keine Erweiterungen oder Unterklassen UIImagePickerController schreiben. Sie müssen lediglich den Delegaten und den Statusleistenstil so einstellen, dass er unverändert bleibt. Dieser Zusatz machte es so, als ob das Problem nie existierte. Es scheint, dass der Stil der Statusleiste beim Drücken auf den Navigationsstapel des UIImagePickerController geändert wird. Um das Problem vollständig zu lösen, musste ich keine Erweiterungen oder Unterklassen UIImagePickerController schreiben. Sie müssen lediglich den Delegaten und den Statusleistenstil so einstellen, dass er unverändert bleibt. Dieser Zusatz machte es so, als ob das Problem nie existierte. Es scheint, dass der Stil der Statusleiste beim Drücken auf den Navigationsstapel des UIImagePickerController geändert wird. Um das Problem vollständig zu lösen, musste ich keine Erweiterungen oder Unterklassen UIImagePickerController schreiben. Sie müssen lediglich den Delegaten und den Statusleistenstil so einstellen, dass er unverändert bleibt. Dieser Zusatz machte es so, als ob das Problem nie existierte.

let pickerController = UIImagePickerController()
pickerController.delegate = self

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

Ich habe tatsächlich eine bessere Möglichkeit gefunden, die Hintergrundfarbe der Statusleiste in der Bildauswahl festzulegen. Grundsätzlich müssen Sie das backgroundImage in der Navigationsleiste auf Null setzen, da in der Bildauswahl standardmäßig ein backgroundImage als weißes Bild vorhanden ist.

André Luiz Alves
quelle