9

enter image description here

When I present the ImagePickerController the statusBar text color is still black, how to make like this?

folse
  • 1,791
  • 1
  • 14
  • 14

7 Answers7

42

Just three steps:

1: Add UINavigationControllerDelegate,UIImagePickerControllerDelegate to your

@interface yourController ()<>

2: imagePickerController.delegate = self;

3:

-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
Akhilrajtr
  • 5,170
  • 3
  • 19
  • 30
folse
  • 1,791
  • 1
  • 14
  • 14
  • 1
    It works because `UIImagePickerController` is a subclass of `UINavigationController` and that delegate method is called every time you present another view controller on the navigation controller stack. – barndog Aug 15 '14 at 22:34
  • 4
    `setStatusBarStyle` is deprecated in iOS 9 – Huy Le May 18 '16 at 01:24
  • @barndog How can I hide status bar when imagePicker shows? There is a bug where cropped images add y offset with size of status bar since bar isn't cropped out. – AnonProgrammer Apr 27 '18 at 00:51
4

Swift solution by writing an extension for UIImagePickerController:

extension UIImagePickerController {
    convenience init(navigationBarStyle: UIBarStyle) {
        self.init()
        self.navigationBar.barStyle = navigationBarStyle
    }
}

Then you can set the color when initializing it:

let picker = UIImagePickerController(navigationBarStyle: .black)    // black bar -> white text

Alternative (inspired by folse's answer): When you initialize the UIImagePickerController normally, make this class the delegate (picker.delegate = self) and implement this function:

func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
    if navigationController is UIImagePickerController {        // check just to be safe
        navigationController.navigationBar.barStyle = .black    // black bar -> white text
    }
}
Community
  • 1
  • 1
Alex Wally
  • 2,299
  • 1
  • 20
  • 18
3

In Swift and iOS 9, setStatusBarStyle is deprecated. You could subclass the controller.

private final class LightStatusImagePickerController: UIImagePickerController {
    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return .lightContent
    }
}
Cesare
  • 9,139
  • 16
  • 78
  • 130
Huy Le
  • 2,503
  • 1
  • 15
  • 15
  • Great suggestion and I think this is the right way to move forward! But for some reason it didn't work for me. The calls are getting called, I tried prefersStatusBarHidden as well, and even called self.setNeedsStatusBarAppearanceUpdate in viewDidLoad. Status bar still shows up as darkContent. – shashwat Jun 07 '16 at 14:18
  • According to Apple documentation of UIImagePickerController you should not subclass the controller. "The UIImagePickerController class supports portrait mode only. This class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified, with one exception. You can assign a custom view to the cameraOverlayView property and use that view to present additional information or manage the interactions between the camera interface and your code." – matrejek Oct 28 '17 at 18:39
  • It doesn't work in iOS 13. The method from subclass is not called. – Igor Kulagin Feb 05 '20 at 14:28
2

I had the same problem having to manage the application runned under different iOS versions.

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

The, in delegate:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    /* Cancel button color  */
    _imagePicker.navigationBar.tintColor = <custom_color>
    /* Status bar color */
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
Luca Davanzo
  • 21,000
  • 15
  • 120
  • 146
2

Using the answers above the following worked for me:

Implement UINavigationControllerDelegate, UIImagePickerControllerDelegate to your UIViewController and set

imagePickerController.delegate = self;

Add the following method:

-(void) navigationController: (UINavigationController *) navigationController willShowViewController: (UIViewController *) viewController animated: (BOOL) animated { 
    navigationController.navigationBar.barStyle = UIBarStyleBlack;
}
kalpesh jetani
  • 1,775
  • 19
  • 33
1

I was facing a similar problem and I found the cleanest way to solve it was to override preferredStatusBarStyle in an extension of UIImagePickerController like so. This principal can be applied to third party libraries nicely.

extension UIImagePickerController {
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        if isLightTheme() {
            return .default // black text
        }
        return .lightContent // white text
    }
}

isLightTheme() is simply a function to determine whether the NavigationBar in that controller is a light or dark colour.

revilo
  • 169
  • 1
  • 8
0

This is the quickest solution I could think of. Create the following category:

@implementation UIImagePickerController (LightStatusBar)

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

@end
Bryan
  • 3,199
  • 3
  • 16
  • 24