How to make UIImagePickerController StatusBar lightContent style? - ios

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

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

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

In Swift and iOS 9, setStatusBarStyle is deprecated. You could subclass the controller.
private final class LightStatusImagePickerController: UIImagePickerController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .lightContent
}
}

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

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

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.

This is the quickest solution I could think of. Create the following category:
#implementation UIImagePickerController (LightStatusBar)
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
#end

Related

hide home indicator for iPhone X

i have an iOS app with video player, when the video is playing (landscape, full screen) i would like to hide the home indicator on iPhone X. I have try with
if (#available(iOS 11.0, *)) {
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
}
and also
-(BOOL)prefersHomeIndicatorAutoHidden{
return YES;
}
but no luck. Does anyone have any idea?
When implementing a container view controller, override
childViewControllerForHomeIndicatorAutoHidden() method if you want
one your child view controllers to determine whether to display the
visual indicator. If you do, the system calls the
prefersHomeIndicatorAutoHidden() method of the returned view
controller. If the method returns nil, the system calls the
prefersHomeIndicatorAutoHidden() method of the current view controller
So if you are using childViewController then need to implement childViewControllerForHomeIndicatorAutoHidden
as -
Swift
extension UINavigationController {
open override func childViewControllerForHomeIndicatorAutoHidden() -> UIViewController? {
return DemoViewController.loadFromNib()
}
}
//DemoViewController is childViewController
class DemoViewController: UIViewController {
static func loadFromNib() -> DemoViewController{
let storyBoardInst = UIStoryboard(name: "Main", bundle: nil)
return storyBoardInst.instantiateViewController(withIdentifier: "DemoViewController") as! DemoViewController
}
override func prefersHomeIndicatorAutoHidden() -> Bool {
return true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
view.backgroundColor = .red
if #available(iOS 11.0, *) {
//Notifies UIKit that your view controller updated its preference regarding the visual indicator
setNeedsUpdateOfHomeIndicatorAutoHidden()
}
}
}
Objective C-
#interface UINavigationController(custom)
#end
#implementation UINavigationController(custom)
-(UIViewController *)childViewControllerForHomeIndicatorAutoHidden{
return [self.storyboard instantiateViewControllerWithIdentifier:#"DemoViewController"];
}
#end
//DemoViewController is childViewController
#interface DemoViewController ()
#end
#implementation DemoViewController
-(BOOL)prefersHomeIndicatorAutoHidden{
return YES;
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
self.view.backgroundColor = [UIColor redColor];
//Notifies UIKit that your view controller updated its preference
// regarding the visual indicator
if (#available(iOS 11.0, *)) {
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
}
}
Output -

Is is possible to change title of `UIImagePickerController`when choosing videos?

I have open photo gallery for choosing video. Here is my code :


- (void)selectMediaFrom:(UIImagePickerControllerSourceType)sourceType {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = sourceType;
imagePicker.delegate = self;
//imagePicker.allowsEditing = YES;
if (selectedMediaType == MediaVideos) {
imagePicker.mediaTypes = #[(NSString *)kUTTypeMovie, (NSString *)kUTTypeVideo];
if (sourceType == UIImagePickerControllerSourceTypeCamera) {
imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
}
}
else if (selectedMediaType == MediaPhotos) {
imagePicker.mediaTypes = #[(NSString *)kUTTypeImage];
if (sourceType == UIImagePickerControllerSourceTypeCamera) {
imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
}
}
if (IS_IPHONE) {
[self presentViewController:imagePicker animated:TRUE completion:nil];
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
[self setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:imagePicker animated:TRUE completion:nil];
});
}
}


And it is always showing title of UIImagePickerController as Photos, See screenshot I have attached.
But, I have open iPhone default Photos app and check, that shows videos folder : See below
Then why it is not showing Videos title ? Can we change it ?
Yes You can change the title of Navigation which you want.
Add the delegate of UINavigationControllerDelegate
Swift 3.0
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool){
viewController.navigationItem.title = "Kirit Modi"
}
Objective C
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
[viewController.navigationItem setTitle:#"Kirit Modi"];
}
See Output :
Thanks for this. I was able to adapt for my situation. Because I present my ImagePicker programmatically from another VC, I had to use similar code.
I first created a variable for the presenting VC:
let imagePickerController = UIImagePickerController()
And then later in the presenting VC, I used:
Swift 4
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
// change title here to something other than default "Photo"
imagePickerController.navigationBar.topItem?.title = "choose photo"
}
It works well. Hope this helps someone.

How to create uitabbar item on swift without a View Controller lined to it

So my problem is I'm creating a UITabBarController without a storyboard and I'm stuck with how to create a UITabBar item without a Viewcontroller. Because what I want to do is the 2nd item of my UITabBarItem is an action not presenting a view controller.
I implement something like this in an app (the close button), though I use storyboards. The close button is a viewController, but I used the following code to get it to act like a regular button:
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
// this provides UI feedback that the button has been pressed, even though it leads to the dismissal
if viewController == self.viewControllers![4] {
viewController.tabBarItem.image? = UIImage(named: "TabBarClose")!.imageWithColor(UIColor.red).withRenderingMode(UIImageRenderingMode.alwaysOriginal)
return false
} else {
return true
}
}
override func viewDidDisappear(_ animated: Bool) {
//sets the close button back to original image
self.viewControllers![4].tabBarItem.image = UIImage(named: "TabBarClose")!
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
// this is so it never actually goes to the close buttons viewController
currentTab = self.selectedIndex != 4 ? self.selectedIndex:currentTab
saveTabIndexToPreferences(currentTab!)
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
// assign functionality to the close button
if item.tag == 100 {// this is old code, there is probably a better way to reference the tab
dismissTabBar()
} else {
}
}
EDIT (for a question that was asked)
func selectTabIndexFromPreferences() {
let defaults:UserDefaults = UserDefaults.standard
selectedIndex = defaults.integer(forKey: "songSelectionTabIndex_preference")
}
func saveTabIndexToPreferences(_ index:Int?) {
if index != nil {
let defaults:UserDefaults = UserDefaults.standard
defaults.set(index!, forKey: "songSelectionTabIndex_preference")
}
}
If you really want to do this (it's pretty nonstandard UI...), then you could add an empty view controller, but in your tab bar delegate implement
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
}
There is an API conform way to do this.
The UITabBarControllerDelegate has a shouldSelect method that you can implement: https://developer.apple.com/documentation/uikit/uitabbarcontrollerdelegate/1621166-tabbarcontroller
Something along these lines:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if (viewController == self.centerViewController) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Test" message:#"This is a test" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[tabBarController presentViewController:alert animated:YES completion:nil];
return NO;
}
return YES;
}

Safari View Controller uses wrong status bar color

My app uses a dark navigation bar color. Therefore I set the status bar color to white (so it has a nice contrast).
I did this by setting the barStyle to black (to make the status bar white) and also setting the barTint to my dark red color. Works perfectly.
I present a SafariViewController like this:
func openWebsite(urlString: String) {
if let url = NSURL(string: urlString) {
let svc = SFSafariViewController(URL: url)
svc.delegate = self
self.presentViewController(svc, animated: true, completion: nil)
}
}
However the status bar of the presented SafariViewController still is white. This is a problem because the SVC navigation bar has the default white transparent iOS default style. So the status bar is basically invisible.
How can I fix that?
You can achieve that by wrapping SFSafariViewController with subclassed UINavigationController.
BlackStatusBarNavigationController.h
#interface BlackStatusBarNavigationController : UINavigationController
#end
BlackStatusBarNavigationController.h
#interface BlackStatusBarNavigationController ()
#end
#implementation BlackStatusBarNavigationController
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleDefault;
}
#end
Use like this:
UINavigationController *navigationController = [[BlackStatusBarNavigationController alloc] initWithRootViewController:viewController];
navigationController.navigationBarHidden = YES;
[self presentViewController:navigationController animated:YES completion:nil];
There are 2 ways you can override preferredStatusBarStyle in your viewControllers and return the one you want
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .Default
}
or you can set it manually with
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
UIApplication.sharedApplication().setStatusBarHidden(false, withAnimation: UIStatusBarAnimation.None)
how ever for setting it through sharedApplicaion you will need to add this in to your plist
"View controller-based status bar appearance" to NO
If you want to set background color of status bar for iOS 13+, you can try to set it force like this.
import UIKit
import SafariServices
class CustomSFSafariViewController: SFSafariViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if #available(iOS 13.0, *) {
UIApplication.shared.statusBarView?.backgroundColor = .purple
}
setNeedsStatusBarAppearanceUpdate()
}
}
extension UIApplication {
#available(iOS 13.0, *)
var statusBarView: UIView? {
let tag = 3848245
let keyWindow = connectedScenes
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows.first
if let statusBar = keyWindow?.viewWithTag(tag) {
return statusBar
} else {
let height = keyWindow?.windowScene?.statusBarManager?.statusBarFrame ?? .zero
let statusBarView = UIView(frame: height)
statusBarView.tag = tag
statusBarView.layer.zPosition = 999999
keyWindow?.addSubview(statusBarView)
return statusBarView
}
}
}
There are few useful properties for customization of SFSafariViewController which you can use:
preferredControlTintColor (color of toolbar items)
preferredBarTintColor (color of toolbar)
P.S. don't forget to use CustomSFSafariViewController instead of SFSafariViewController. You can do it like this.
let safariViewController = CustomSFSafariViewController(url: url)

How to give Title in UIImagePickerController?

I want to give title in UIImagePickerController as shown in image screen shot
Set UIImagePickerController delegate to self and implement the following method of UINavigationControllerDelegate:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[viewController.navigationItem setTitle:#"<Your-Title>"];
}
You try this code:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
UINavigationItem *ipcNavBarTopItem;
// add done button to right side of nav bar
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Photos"
style:UIBarButtonItemStylePlain
target:self
action:#selector(saveImages:)];
UINavigationBar *bar = navigationController.navigationBar;
[bar setHidden:NO];
ipcNavBarTopItem = bar.topItem;
ipcNavBarTopItem.title = #"Photos";
ipcNavBarTopItem.rightBarButtonItem = doneButton;
}
You need to implement the delegate method for UINavigationController, in Swift:
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
viewController.navigationItem.title = "Some title"
}

Resources