preferredStatusBarStyle for native controllers - ios

Since apple introduced UIViewControllerBasedStatusBarAppearance and preferredStatusBarStyle in iOS 7 I'm trying to understand whats best practice to change status bar color for built in view controller, like:
UIImagePickerController
MFMailComposeViewController
UISearchDisplayController
for example, when using UISearchDisplayController, I want to change the status bar from light to dark when the search bar appears.
how can I do that? do I need to subclass UISearchDisplayController? maybe category?
and what about UIImagePickerController it has its own stack of view controllers, how can change the status bar style for all of them when presenting the photo picker?
until now I used the global why of
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
but now its all per-ViewController approach, so how would I modify controllers that are not mine?

Yes, you can subclass those classes to change the status bar appearance. According to UIImagePickerController, it's just a subclass of the UINavigationController, so, if you subclass and implement preferredStatusBarStyle in your subclass, all other view those appear on navigation will have the same status bar. Good Luck!

Related

Apple News app scrolling buttons in UINavigationBar

How to implement such a navigation bar? I am aware of the title view but not aware of any subtitle view.
One way I can think of is setting UINavigationBar shadow image to nil and place collection view below the navigation bar. But that won't give me translucency of Navigation bar.
Is there a native way (which may have been introduced in iOS9) of doing so?
I think you'll have to make custom view and will have to use it as navigation bar. Hide the default navigation bar and use your custom view.
I wanted to make the nav.bar as shown in picture with the functionality like tab bar and i've made custom view for that purpose.
You can use a library like PageMenu or PagingMenuController to do this easily.

UIImagePickerController vs status bar iOS8

I'm subclassing UIImagePickerController in attempt to override its default status bar behavior and having mixed results. My app uses view controller-based status bar appearance.
Without subclassing, I'm finding that it changes the status bar style to Default (dark) when the picker is dismissed, and nothing I've tried yet in my initial view controller is fixing it. Also, when the picker hides the status bar while being presented, sliding it upwards, the initial view controller's navigation bar slides up with it from height 64 to 44.
So I want my UIImagePickerController subclass to keep the status bar style as LightContent and, in an attempt to work-around the sliding navigation bar, keep the status bar showing while presenting the picker, then hide it on viewDidAppear:.
The first interesting thing is that preferredStatusBarStyle and prefersStatusBarHidden in my picker subclass weren't called at all until I also overrode childViewControllerForStatusBarStyle and childViewControllerForStatusBarHidden to return nil. This seems to indicate that normally, a UIImagePickerController is overriding those, probably to return an internal child view controller. Looking at the view hierarchy in viewDidAppear:, there's certainly a child PLImagePickerCameraView and its likely there's a controller to go with it. Sadly we cannot override this controller.
Overriding those childViewControllerFor... methods, preferredStatusBarStyle and prefersStatusBarHidden do get called in-between viewWillAppear: and viewDidAppear:, and can indeed keep the status bar visible and LightContent. The second interesting thing though, is that before the presentViewController animation the status bar briefly blinks dark. No amount of extra calls to setNeedsStatusBarAppearanceUpdate in viewWillAppear: or other places such as viewDidLoad: seem to prevent that.
The third interesting thing is that the bar style is still getting set to dark during dismissal, and no extra calls to setNeedsStatusBarAppearanceUpdate in the picker's viewWillDisappear: or viewDidDisappear: seem to prevent that.
tl;dr -- I've found that overriding UIImagePickerController to hide & show the status bar on demand to work pretty well, but setting the bar style is problematic. Something in the picker class or UINavigationController itself is automatically preferring the Default bar style, and when its switched to that on dismissal, it seems difficult to switch it back.
I've seen the Question UIImagePickerController breaks status bar appearance, and nothing I've seen there has helped yet, and iOS8.1 doesn't fix it. I was sure that setting the picker's navigationBar.barStyle to black would do it, but no dice. Any ideas anybody?
(Also, any tips on preventing a UINavigationController's navigation bar from sliding up to 44 height when the status bar is hidden would be useful thx)

UIImagePickerController status bar issue in crop

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

ios7 suddenly navigation bar height change

hi i want to solution in ios7's problem.
My classes is
AlphaViewController : UIViewController,
BetaViewController : UIViewController
when AlphaViewController will appear, Alpha's navigation bar hight is 44.0f.
looks like too. and Supported Orientation is Portrait.
then I use presentmodalViewController for BetaViewController.
BetaViewController's navigation bar will be hide in viewWillAppear.
and Supported Orientation is LandScape.
then I use popViewController function. so AlphaViewController will be appear again.
I use self.navigationController.navigationBarHidden = YES;
But suddenly Alpha's navigation bar hight is changed.
It looks like 22.0f. I don't know reason..
my english is not good.
thanks to read.
first of all presentModalViewController: is deprecated since ios6 so you may not use it for presenting an view controller.
When you present a viewController from an navigationController if you want the navigation bar to be present on AlphaViewController you dont need to hide or un hide. Since you are presenting the BetaViewController navigation bar will not appear and when you dismiss it will be visible again in AlphaViewController.

Navigation Bar Higher like Safari App

I was wondering if there is a way to create a navigationBar like the one in this photo:
http://s2.postimage.org/ewem26czd/foto.jpg
and there is a way to customize its background?
It's fairly easy to customize a UINavigationBar. Simply create a subclass of it, and in the XIB where you find the UINavigationController, use the inspector on the right to change the class of the navigation controller's navigation bar to your subclass.

Resources