0

I'm using UIViewControllerBasedStatusBarAppearance and preferredStatusBarStyle to manage the status bar color and appearance.

My app lets the user choose a photo from his camera roll and crop it to square using the native crop option of UIImagePickerController.

So I push a UIImagePickerController and enable editing to get the crop screen.
The problem is, I want that for the albums and photos view, the status bar will be white, and for the crop view I want to hide the status bar.

how can I do that with preferredStatusBarStyle ?

until now I made a category for UIImagePickerController and implemented:

- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}  

this indeed set the status bar to white color in photos, but when going to crop view, the status bar becomes black, that could be good for me because I want to hide it and the background is black so you can't see it, BUT the battery indicator is green! so you only see the battery indicator in the status bar!

how can I solve that? how can I hide the status bar only in the crop view?

Mario
  • 2,431
  • 6
  • 27
  • 34

2 Answers2

0

You will have to do a little bit of detective work here, but I can give you a lead.

I would suggest to subclass UIImagePickerController and return your statusbar preferences according to displayed child controller.

UIViewController has two methods that allow you to control statusbar visibility and appearance:

- (BOOL)prefersStatusBarHidden;
- (UIStatusBarStyle)preferredStatusBarStyle

Simply override them, no super call needed.

You have access to view controllers stack within subclass so you can choose preferred style and visibility for statusbar according to number of controllers on stack.

I have a feeling that UIKit will ping preferredStatusBarStyle and prefersStatusBarHidden each time new child controller pushed on stack.

If not then you can force UIKit to update statusbar by calling:

[self setNeedsStatusBarAppearanceUpdate]

Since UIImagePickerController is a subclass of UINavigationController you can assign your own delegate to it, monitor when new controller pushed on stack and call the suggested code above.

pronebird
  • 12,068
  • 5
  • 54
  • 82
  • but my problem is that I don't know which controllers the UIImagePickerController is pushing, its all private. for example it can have in stack several view controllers: albums, photos and crop. and if I only wants to hide the status bar in the crop controller, how can I know? – Mario Dec 08 '14 at 08:32
  • Right, you can probably use `NSStringFromClass(self.topViewController.class)` to get a string name for a private class. This way you could identify controllers. – pronebird Dec 08 '14 at 09:38
  • 1
    I think you'll find that a parent view controller's `prefersStatusBarHidden` isn't called again when a child is pushed, not unless `setNeedsStatusBarAppearanceUpdate` is used. – Pierre Houston Dec 23 '14 at 21:22
  • @smallduck looking at my answer today, I think you're totally right. – pronebird Dec 23 '14 at 23:41
0

Sort of a followup to Andy's post, yes subclassing UIImagePickerController used to be forbidden but is allowed now. There's some unexpected issues trying to override prefersStatusBarHidden and preferredStatusBarStyle though.

Note how UIImagePickerController is a subclass of UINavigationController and so itself is a container for child view controllers. How a container view controller controls status bar visibility and style to its children is by overriding childViewControllerForStatusBarHidden and childViewControllerForStatusBarStyle. In general UINavigationController doesn't implement those and usually one overrides them to return the currently visible view controller.

In a case like this though, where you don't control the child view controllers, your picker subclass can override these methods to return nil, and then your implementations of the prefer methods should take over. In theory, you then just have to make them return what you need at the right time, but as evidenced by my experience, there's something fishy going on with UIImagePickerController and the status bar style.


For my own UIImagePickerController subclass, I don't care about child view controllers given its custom UI, but I've experimented with returning nil from childViewController.. and overriding the prefer methods. I've found that controlling the visibility to work fine, but something in the picker to counteract my subclass returning LightContent from preferredStatusBarStyle. See my own question.

Community
  • 1
  • 1
Pierre Houston
  • 1,631
  • 20
  • 33