I've this strange issue when i'm presenting a MFMessageComposeViewController in my app!
I don't know what this black bar is and i'm unable to remove the app logo from the NavigationBar.
And here is the code for presenting the controller
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
[[messageController navigationBar] setBarTintColor:SMAN_ORANGE_COLOR];
[[messageController navigationBar] setTintColor:[UIColor whiteColor]];
messageController.messageComposeDelegate = self;
[messageController setRecipients:recipents];
[messageController setBody:message];
// Present message view controller on screen
[self presentViewController:messageController animated:YES completion:nil];
To remove the app logo, try to add in your method above the following code:
messageController.navigationItem.titleView = [UIImageView new];
To change the Status Bar style (White Color) add the following code before presenting the messageController:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
Also in your .plist file set:
View controller-based status bar appearance to NO
I solve the issue subclassing my UINavigationController and changing the appearance of it with [UINavigationBar appearanceWhenContainedIn:[myNavControllerSubclass class], nil]
[self presentViewController:messageController animated:YES completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO];
}];
this works in ios 8 for the white status bar
Refer answer #1 also.
As per Apple's documentation you can only present it modally.
[self presentModalViewController:messageController animated:YES];
I'm attempting to do a presentViewController with an UIImagePickerControl in order to display a standard Camera Roll photo picker. This works end-to-end in most of my app. The place where it does not work is when I want to use the imagePicker inside an already presented viewController; the view to present the album is unable to be presented.
The basic idea is I'm trying to either access the rootViewController on the window object, or the app delegate's persisted tabBarController (which is the rootViewController); both as examples of top level items that are hopefully always present. Just using "self" otherwise ends up as a partial view presenting it.
Is there a reliable way to presentViewController inside an already presentedView?
dispatch_async(dispatch_get_main_queue(), ^ {
// 1. attempt that works well elsewhere in app
[((AppDelegate*)[[UIApplication sharedApplication] delegate]).tabBarController presentViewController:self.imagePickerController animated:YES completion:nil];
// 2. this does nothing, no crash or action (_UIAlertShimPresentingViewController)
[[[UIApplication sharedApplication] keyWindow].rootViewController presentViewController:self.imagePickerController animated:YES completion:nil];
// 3. attempt off related internet suggestion, nothing happens
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
[topController presentViewController:self.imagePickerController animated:YES completion:nil];
});
Because presentViewController is meant as a modal presentation, I don't think it's possible to present a second modal at the same time in the same UIWindow. You could, however, add a new UIWindow and present it there.
originalWindow = [[[UIApplication sharedApplication] keyWindow];
tempWindow = [[UIWindow alloc] init];
UIViewController *controller = [[UIViewController alloc] init];
tempWindow.rootViewController = controller;
[tempWindow makeKeyAndVisible];
[controller presentViewController:self.imagePickerController animated:YES completion:nil];
You'll want to add something like this in your response to the image picker's return:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
// Process the result and then...
[self cleanupWindow];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self cleanupWindow];
}
- (void)cleanupWindow {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(madeKeyWindow:) name:UIWindowDidBecomeKeyNotification object:nil];
[originalWindow makeKeyAndVisible];
}
- (void)madeKeyWindow:(NSNotification *)notification {
[tempWindow removeFromSuperview];
tempWindow = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIWindowDidBecomeKeyNotification object:nil];
}
In iOS 6, I was using the following code to push a UIImagePickerController, of source type UIImagePickerControllerSourceTypeCamera, and to show its navigation bar. I wanted to show the navigation bar because after taking the image, I'm pushing another VC that allows the user to set some attributes in the database.
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
cameraController = [[UIImagePickerController alloc] init];
cameraController.delegate = self;
cameraController.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:cameraController animated:YES completion:NULL];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
cameraController.topViewController.title = #"Add";
cameraController.navigationBar.translucent = NO;
cameraController.navigationBar.barStyle = UIBarStyleDefault;
[cameraController setNavigationBarHidden:NO animated:NO];
}
In iOS 7 this code no longer shows the navigation bar. Does anyone know if there's a way to to get the navigation bar back for UIImagePickerController, of source type UIImagePickerControllerSourceTypeCamera?
Guess what? When imagePicker presents, it's automatic set to hidden....
All you need to do is setHidden:NO in next runloop. Like:
[self presentModalViewController:imagePicker animated:YES];
[self performSelector:#selector(showNavigationBar:) withObject:imagePicker afterDelay:0];
- (void)showNavigationBar:(UIImagePickerController*)imagePicker {
[imagePicker setNavigationBarHidden:NO];
}
#LeverkusenFan's solution works well. But instead of using a hack such as a run loop, you use the completion handler of presentViewController to achieve that effect.
[self presentViewController:cameraController animated:YES completion:^{
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
cameraController.topViewController.title = #"Add";
cameraController.navigationBar.translucent = NO;
cameraController.navigationBar.barStyle = UIBarStyleDefault;
[cameraController setNavigationBarHidden:NO animated:NO];
}];
In fact a better solution that avoids the weird animation when the navigation bar shows up and which works well when you press the back button on the nav bar is as follows:
In the delegate for the UIImagePickerController implement the following function.
- (void) navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (navigationController == self.cameraController && navigationController.viewControllers.count == 1) {
// When showing the ImagePicker update the status bar and nav bar properties.
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
navigationController.topViewController.title = self.cameraTitle;
navigationController.navigationBar.translucent = NO;
navigationController.navigationBar.barStyle = UIBarStyleDefault;
[navigationController setNavigationBarHidden:NO animated:animated];
}
}
This function will get called when the ImagePicker is shown and we only make the changes for the rootViewController of the ImagePicker (i.e. the camera screen).
I am new to iOS development. I am trying to hide status bar in UIImagePickerController. Whenever I click on "Take photo", status bar appears. It doesn't hide. I want status bar to be hidden only in UIImagePickerController.
Here is my code,
- (IBAction)takePhoto:(UIButton *)sender
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self statusBar:YES];
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:NULL];
}
-(void)statusBar:(BOOL)status
{
[[UIApplication sharedApplication] setStatusBarHidden:status];
}
How to hide the status bar on UIImagePickerController?
This worked fine for me:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
Edit: As of today i just found out that in your info.plist, if you just copy-paste view controller-based status bar appearance there it won't work ... you have to hit enter on a property, and scroll to the last one of them so you will have autocomplete to :view controller-based status bar appearance and an boolean, with no. I tried multiple times but it does not work just copying. Have a nice day.
The solution I found for applications build around :
"View controller-based status bar appearance" set to YES
I did add Category:
//UIImagePickerController+StatusBarHidden.h
#import <UIKit/UIKit.h>
#interface UIImagePickerController (StatusBarHidden)
#end
//UIImagePickerController+StatusBarHidden.h
#import "UIImagePickerController+StatusBarHidden.h"
#implementation UIImagePickerController (StatusBarHidden)
-(BOOL) prefersStatusBarHidden {
return YES;
}
-(UIViewController *) childViewControllerForStatusBarHidden {
return nil;
}
#end
The method childViewControllerForStatusBarHidden is used rarely, but image picker do use it, thats why might cause some troubles
You may also implement UIViewController singleton, with method which returns YES or NO, based on its property.
Then your View controleller implements childViewControllerForStatusBarHidden returning the above singleton.
Changing singleton property automatically change statusbar in app. There also is twin method childViewControllerForStatusBarStyle
However for 2014, iOS8, see this https://stackoverflow.com/a/18960308/294884
I had an issue where in iOS7 my status bar was not being hidden. I hid it programmatically and it still displayed in iOS7, but when ran in iOS6 the status bar would hide appropriately. You have to go to the plist and add the following:
'view controller-based status bar appearance' and set to NO.
If you want the status bar to re-appear in other view controllers and only be hidden on a particular VC, then you set the status bar to hidden YES when the VC loads.
When the VC will disappear you set the status bar hidden back to NO.
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
and when the controller will disappear you add the following to set the status bar so it is no longer hidden and will display on the next View:
-(void)viewWillDisappear:(BOOL)animated{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
setStatusBarHidden:withAnimation: if you want some smooth animation
subclass UIImagePickerController ... mine is V1ImagePickerController ...
.m file looks like this:
#import "V1ImagePickerController.h"
#interface V1ImagePickerController ()
#end
#implementation V1ImagePickerController
- (void)viewDidLoad
{
[super viewDidLoad];
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) // iOS7+ only
{
self.edgesForExtendedLayout = UIRectEdgeNone;
[self prefersStatusBarHidden];
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate)];
}
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (UIViewController *)childViewControllerForStatusBarHidden
{
return nil;
}
#end
the childViewControllerForStatusBarHidden is the key!
If you want to disable the status bar from plist, try this:
Status bar is initially hidden : YES
View controller-based status bar appearance : NO
this is necessary for iOS 7, works for me. I do not know if there are some other techniques for doing this in iOS7. Set these two tags in your info.plist.
Everytime your viewcontroller appears, in viewDidLoad or when image picker controller finishes , use this:
- (void) imagePickerController:(UIImagePickerController *)picker1 didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
.
.
.
.
}
I used Silvertaurus's answer above, but with a little modification to the prefersStatusBarHidden method that I thought was very helpful:
//UIImagePickerController+StatusBarHidden.h
#import <UIKit/UIKit.h>
#interface UIImagePickerController (StatusBarHidden)
#end
//UIImagePickerController+StatusBarHidden.h
#import "UIImagePickerController+StatusBarHidden.h"
#implementation UIImagePickerController (StatusBarHidden)
-(BOOL) prefersStatusBarHidden {
if (self.sourceType==UIImagePickerControllerSourceTypeCamera) {
return YES;
} else {
return NO;
}
}
-(UIViewController *) childViewControllerForStatusBarHidden {
return nil;
}
#end
This keeps the status bar up for the image picker when the camera is not displayed.
Try this
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];
Also check this discussion.
Please try this.
• Setting a delegate for the UIImagePickerController
• hide the status bar in the delegate's
navigationController:didShowViewController:animated: function.
E.G:
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
You can do it with a category:
#interface UIImagePickerController (HideStatusBar)
#end
#implementation UIImagePickerController (HideStatusBar)
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (UIViewController *)childViewControllerForStatusBarHidden
{
return nil;
}
#end
Source: https://gist.github.com/psobko/9493473
-(IBAction)takePhoto:(UIButton *)sender
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self statusBar:TRUE];
[self presentViewController:picker animated:YES completion:NULL];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
[self statusBar:FALSE];
[picker dismissViewControllerAnimated:YES completion:NULL];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self statusBar:FALSE];
[picker dismissViewControllerAnimated:YES completion:NULL];
}
-(void)statusBar:(BOOL)status
{
[[UIApplication sharedApplication] setStatusBarHidden:status];
}
that might help you to achieve what you want.
Try my answer posted here if you want to keep using ViewController-Based Status Bar Appearance.
In my case I had to use presentViewController to show UIImagePickerViewController (iOS7).
1- Set View controller-based status bar appearance to NO in .plist
2- Create a category for UIImagePickerController and in viewDidLayoutSubviews:
- (void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
3- Added the two following methods to the category:
- (BOOL)prefersStatusBarHidden{
return YES;
}
- (UIViewController *)childViewControllerForStatusBarHidden{
return nil;
}
I hope this will help.
i think i solved this in a pretty simple way without subclassing and using plist.
it only hides for UIImagePickerController.
this example is for bringing up the photo gallary only, but i imagine you can apply it in the same way to anywhere with in uiimagepickercontroller
- (void)showGallary
{
[CATransaction begin];
[CATransaction setCompletionBlock:^{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}];
imgPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[CATransaction commit];
}
I have the UIImagePickerController as a content View Controller for the UIPopoverController. I need to detect when the popover has just finished presented (has just showed up). UIPopoverController does not have any delegate for this. I can't seem to find a way to detect the UIImagePickerController as well. (This is for iPad)
Any suggestions?
// UIImagePickerController let's the user choose an image.
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
self.popover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
self.popover.delegate = self;
[self.popover presentPopoverFromBarButtonItem:self.openPhotosButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
The UIImagePickerDelegate is also a UINavigationControllerDelegate.
Your class should implement UINavigationControllerDelegate and include the following:
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
// [navigationController setNavigationBarHidden:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES]; // This one works for me: OP
}
I've tested this and it hides the navigation bar. I am not sure if doing so conflicts with the HIG though.
Thise should help:
UIImagePickerControllerDelegate and imagePickerController:didFinishPickingMediaWithInfo:
UIPopoverControllerDelegate popoverControllerDidDismissPopover
You have delegates for both