UIImagePickerControllerがステータスバーの外観を壊す


137

私の.plistファイルでは、「コントローラーベースのステータスバーの外観の表示」をに設定していNOます。しかしその後UIImagePickerController、私のアプリはオプションがに設定されているかのように動作しますYES

私のアプリでは、を提示するVCを提示しUIImagePickerControllerます。

問題は次のように発生します:

  • 写真ピッカーが表示された後、写真ライブラリが選択されると、ステータスバーのテキストの色が変わります。
  • 次に、UIImagePickerControllerが閉じられると、残りのアプリのステータスバーの間隔が変更され、他のコントローラーのすべてのナビゲーションバーがステータスバーの下に表示されます。

ビューコントローラーでステータスバーを管理せずにこれを解決する方法はありますか?


私の場合の答えは、childviewcontrollersに関連付けられていました。それらを再利用する代わりに再作成する必要がありました。
Alex L

7
これは本当にiOS 7のバグのようですが、誰かがAppleに報告を提出しましたか?
Dan F

stackoverflow.com/questions/21225978/…単純なソリューションでの同様の質問
Ting Wu

@AlexLさん、どうしてそれが起こるのか知っていますか?
Shabarinath Pabba 2015年

回答:


192

上記の解決策はどれもうまくいきませんでしたが、Rich86manとiOS_DEV_09の答えを組み合わせると、一貫して機能する解決策が得られます。

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

そして

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

この素晴らしいソリューションについて。2014 / iOS8の場合、いくつかのケースprefersStatusBarHiddenで、ALSOを含める必要があることもありました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...

それが誰かを助けることを願って


3
これは(Rich86manが言ったように)トリックです:「UIImagePickerControllerはNavigationコントローラーの一種であるため、UINavigationControllerデリゲートとしても設定しています。」
2013年

2
UIImaegPicker ..を閉じた後はどうですか?ステータスバーをfalseに設定すると、背景が黒くなります。
Nitin Gohel 2014年

上記の質問に従ってplistを設定していますか?
dpjanes 2014年

UIImagePickerControllerSourceTypePhotoLibraryを使用していくつかのアルバムを開き、少しパンしてジェスチャーをキャンセルすると、問題に気づきましたか?
クコスク2014年

3
これは機能しますが、ステータスバーが非常にぎくしゃくした動きで飛び出します。Appleにバグを報告しました。
jjxtra 2014年

84

今日も同じ問題に直面しました。これが私の解決策です。

画像ピッカーを呼び出すビューコントローラーで、自分を画像ピッカーのデリゲートとして設定します。(あなたはおそらくこれをすでにやっています)

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

UIImagePickerControllerはNavigationコントローラーの一種であるため、UINavigationControllerデリゲートとしても設定しています。次に:

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

UIStatusBarStyleLightContentを、探しているスタイルに置き換えます。


10

.plistファイルで[ビューコントローラーベースのステータスバーの外観]が[いいえ]に設定されている場合、承認された回答が機能します。実際に他のビューコントローラーでステータスバーを制御し、このオプションをYESに設定する必要がある場合、UIImagePickerControllerを正しく動作させる別の方法は、サブクラス化することです。

// .h
@interface MYImagePickerController : UIImagePickerController
@end

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

6

私は同じ問題に直面しました。

これが私の解決策です。これを、画像ピッカーを開いているビューコントローラーのviewWillAppearに配置します

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

[[UIApplication sharedApplication] setStatusBarHidden:YES];

}

4

これを試して頂けますか?needsStatusBarApperanceUpdateが機能すると思います。

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

4

これは適切な処理を提供するために見つかりました、2つの部分があります。

- (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自体がビューコントローラーを提供するため、このデリゲートはスタック上のすべてのプレゼンターに対して機能します。

viewWillAppearは、表示しているビューコントローラがその上を閉じるたびに、このビューコントローラ自体が常にリセットされるようにします。


3

同じ問題がありました。情報plistに追加:値が「NO」の「コントローラーベースのステータスバーの外観を表示」

ここの例https://stackoverflow.com/a/19211669

この解決策は私にとってはうまくいきます。


2

これはおそらくバグです。「ビューコントローラーベースのステータスバーの外観」をYESに設定し、すべてのビューコントローラーで次のコードを貼り付けて問題を解決しました。

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

その後、私のアプリは期待どおりに動作します。


2

UIImagePickerのステータスバーを非表示にする場合:

-

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

また、UIImagePickerが閉じてビューコントローラーのステータスバーを非表示にする場合は、次のコードを使用します。

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

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}

2

これを試して ....

これはどちらの場合でも機能します。つまりpresentModalViewControllerとpushViewControllerのどちらを使用するか

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

デリゲートメソッド

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

上記のすべてが私にはうまくいきませんでした。プレゼンテーションスタイルを次のように変更して問題を解決しました。

imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;

2

上記の解決策のどれも私にとってうまくいきませんでした。

モーダルビューコントローラーとしてUIImagePickerControllerを提示します。UIImagePickerControllerを閉じた後のステータスバーの状態は次のとおりです。

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

問題を修正した解決策は、UIImagePickerControllerを閉じた後にstatusBarOrientationを復元することでした:

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

...

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

2

このコードは、ステータスバーのスタイルをカスタマイズするのに役立ちました。

編集:このソリューションは、「コントローラーベースのステータスバーの外観を表示する」==はいの場合に機能します

@implementation UIImagePickerController (IOS7_StatusBarStyle)

-(UIViewController*)childViewControllerForStatusBarStyle
{
   return nil;
}

-(UIStatusBarStyle)preferredStatusBarStyle
{
   return UIStatusBarStyleLightContent;
}

@end

2

上記の答えはすべて問題なく、役に立ちます。

異なる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];

次に、デリゲートで:

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

一部の状況で機能する可能性のあるさらに別のソリューション。

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

1

現在の[self setNeedsStatusBarAppearanceUpdate]ビューコントローラが再表示されたときに呼び出してみましたか?


それはおそらくバグです–私はサンプルプロジェクトでレーダーを提出し、ステータスバーを管理する古いシステムにフォールバックします:(
Ash

1

iOS7のUIImagePickerControllerでステータスバーを非表示にしようとしましたが、これを行う方法がまだわかりません。私が使う

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

UIImagePickerControllerを呼び出すViewControllerで、plistファイルに「View controller-based status bar appear = NO」を設定します。これがお役に立てば幸いです。


1

これを試して :

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

そしてプロトコル実装では、これを使用します:

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

1

これは私のためにそれを解決しました...:

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

1

ここでは、私が抱えていた問題(おそらくOPも抱えていた問題)を具体的に修正したものはなかったので、私の答えを共有したいと思いました。バグのある解決策だと思うステータスバーを非表示にする代わりに(ステータスバーを非表示にするべきでないときに、アプリが時々非表示の状態になることに気づきました)。代わりに、を試してみることにしましたUIStatusBarStyles

UIImagePickerControllerのビューが表示されると、デフォルトの背景色が薄い灰色なので、ステータスバーのスタイルをデフォルトに設定します。

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

次に、イメージピッカーが閉じられたら、それをに戻し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

この場合、2つのステップを使用しています

最初のステップ:info.plistに追加:「コントローラーベースのステータスバーの外観を表示」、値「NO」

2番目のステップ:UIImagePickerControllerのデリゲートでこのコードを使用/呼び出します

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

IOS-7の場合、もう1つの機能を追加します

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

1

iOS 8.1では、ようやくこのバグが修正されたようです!私はコードから採用したすべての回避策を取り除くことができました。


1

iOS 8のデフォルトの動作を使用すると、ステータスバーを非表示にしたときに、ステータスバーが表示されないという問題がありました。

私が見つけた解決策presentPopoverは、ビューコントローラーから呼び出した直後に私がしたことです:

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

これをメインのビューコントローラに追加する必要もありました。

- (UIViewController *)childViewControllerForStatusBarHidden
{
    return nil;
}

1

だから私はこの問題を抱えていて、単一のデリゲート関数を実装するだけでそれを解決することができました。ステータスバーの背景は黒なので、アプリケーションのUIStatusBarStyleは.LightContentです。デバイスのストレージから写真を選択するためにUIImagePickerControllerを提示したとき、ステータスバーは問題ありませんでした。ただし、「カメラロール」や「お気に入り」などのディレクトリをクリックすると、ナビゲーションスタックが効果的にプッシュされ、ステータスバーが表示されなくなりました。写真を選択すると、ステータスバーはまったくありませんでした。別のモーダルビューコントローラーを閉じると、バッテリーのみが存在し、残りのステータスバーも黒である可能性があることを示しています。

UIImagePickerControllerの拡張など、他のソリューションをいくつか試しましたが、Swiftでは拡張機能を使用してオーバーライドすることはできません。次に、UIImagePickerControllerをサブクラス化して、viewWillAppear()でステータスバーを非表示にし、viewWillDisappearでステータスバーを再表示しました。.Slideアニメーションを使用してステータスバーの非表示を確認できましたが、ディレクトリを選択するとステータスバーが非表示になるため、ステータスバーの再表示を確認できませんでした。繰り返しになりますが、モーダルビューコントローラーを閉じると、残りのステータスバーが見えなくなり、緑色のバッテリーが元に戻りました。また、prefersStatusBarHidden()をオーバーライドしようとしましたが、その関数は呼び出されなかったため、setNeedsStatusBarAppearanceUpdate()を呼び出して、prefersStatusBarHidden()が確実に呼び出されるようにしましたが、まだ呼び出されていません。また、デリゲートメソッドnavigationController willShowViewControllerでステータスバーを非表示にするように設定する提案があります。この場合も、ステータスバーを非表示にするだけで問題は解決しません。結局のところ、UIImagePickerControllerのナビゲーションスタックにプッシュすると、ステータスバーのスタイルが変更されるようです。問題を完全に解決するために、拡張機能やサブクラスのUIImagePickerControllerを記述する必要はありませんでした。必要なのは、デリゲートを設定し、ステータスバーのスタイルを同じままに設定することだけです。この追加により、問題が存在しないかのようになりました。UIImagePickerControllerのナビゲーションスタックにプッシュすると、ステータスバーのスタイルが変更されるようです。問題を完全に解決するために、拡張機能やサブクラスのUIImagePickerControllerを記述する必要はありませんでした。必要なのは、デリゲートを設定し、ステータスバーのスタイルを同じままに設定することだけです。この追加により、問題が存在しないかのようになりました。UIImagePickerControllerのナビゲーションスタックにプッシュすると、ステータスバーのスタイルが変更されるようです。問題を完全に解決するために、拡張機能やサブクラスのUIImagePickerControllerを記述する必要はありませんでした。必要なのは、デリゲートを設定し、ステータスバーのスタイルを同じままに設定することだけです。この追加により、問題が存在しないかのようになりました。

let pickerController = UIImagePickerController()
pickerController.delegate = self

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

-1

実際に、イメージピッカーでステータスバーの背景色を設定するより良い方法を見つけました。基本的に、navigationBarのbackgroundImageをnilに設定する必要があります。これは、Image PickerのデフォルトでbackgroundImageが白い画像として設定されているためです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.