iOS SDK - How to get the status bar back when using UIImagePickerController? - iphone

As soon as I add a UIImagePickerController sub view to my view the status bar disappears and I can't get it back. Is there any way to keep the status bar visible?
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self.view addSubview:imagePicker.view];
[imagePicker viewWillAppear:YES];
[imagePicker viewDidAppear:YES];
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];

I had to do the same thing in a camera app as well. Apparently, in addition to setting the status bar to not be hidden, you also have to reset its style after the camera view makes it disappear. Try this:
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];

The accepted answer's solution got deprecated meanwhile.
Use
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
instead of
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
Valid values for the animation parameter are UIStatusBarAnimationNone, UIStatusBarAnimationFade, UIStatusBarAnimationSlide. Details are found in the documentation.

After reading this and finding none of the answers worked, I managed to get it working by doing the following:
• Setting a delegate for the UIImagePickerController
• In that delegate, 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:NO];
}

Add your UIImagePicker to the root view (i.e. a Navigation Controller or TabbarController)
[self.tabBarController presentModalViewController:imagePickerController animated:YES];
After that you can use
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
// do your stuff
[picker dismissModalViewControllerAnimated:YES];
}
to close your ImagePicker.

well, I know you are not supposed to do this, but if you subclass UIImagePickerController, you can put that in your custom class:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];
}

None of the solutions worked on iOS 5.1.1
Tim's solution worked on iOS 4.2.1
The only way I was able to fix the problem on iOS 5.1.1 was like that
-(void)viewDidAppear:(BOOL)animated
{
double delayInSeconds = 0.01;
dispatch_time_t popTime =
dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[[UIApplicationsharedApplication] setStatusBarHidden:NO];
});
which is very hacky and wrong.
I spent half a day looking for a solution and then decided to just use AVFoundation approach and it took me an hour to implement the same basic photo capture that I needed using AVCaptureSession and AVCaptureStillImageOutput. And it works better too - AVCaptureSession starts faster than UIImagePickerController and AVCaptureVideoPreviewLayer has a much better frame rate on modern devices compared to UIImagePicker camera preview.

Related

iOS 7 UIImagePickerController Camera Covered with Static image

iOS 7 using UIImagePickerController to take picture twice, at second time will show a static image covered the camera, how to reset the camera.
I'm try to take picture one by one, and keep take 5 pictures.
It works on iOS6.
on iOS7, it works fine at the first time, but when it take picture at second time, it will show a static dark image on screen, how to clear or reset it, although take picture works, but user can't see what will capture with camera.
bool fistTimeToShow = YES;
-(void) viewDidAppear:(BOOL)animated{
if (fistTimeToShow) {
fistTimeToShow = NO;
self.imagePickerController = nil;
[self tackImage];
}
}
-(void)tackImage{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.imagePickerController = [[UIImagePickerController alloc]init];
self.imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imagePickerController.showsCameraControls = YES;
self.imagePickerController.delegate = self;
[self presentViewController:self.imagePickerController animated:NO completion:nil];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSLog(#"====== imagePickerController:didFinishPickingMediaWithInfo ======");
[self.imagePickerController dismissViewControllerAnimated:NO completion:nil];
//...deal with the image capture...
self.imagePickerController = nil;
[self tackImage];
}
Update
I change the dismiss function to put the [self tackImage]; in block. And now it always show the fist image took.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSLog(#"====== imagePicker: didFinish ======");
self.imagePickerController = nil;
[self dismissViewControllerAnimated:NO completion: ^{
[self tackImage];
}];
}
I'm trying to find a way to clear the image. But I don't know where the image saved yet.
Update2
use
[self performSelector:#selector(presentCameraView) withObject:nil afterDelay:1.0f];
and function
-(void)presentCameraView{
[self presentViewController:self.imagePickerController animated:NO completion:nil];
}
to replace. [self presentViewController:self.imagePickerController animated:NO completion:nil]; it works on my device anyway, but I don't even know why.
Update3
I have set the userInteractionEnabled to NO when Delay:1.0f to avoid other problems, and may be also need set the navigationBar and tabBar for specifically use.
I had exactly the same issue under iOS 7 using Xamarin.iOS.
What has helped, is adding GC.Collect() in didFinishPickingMediaWithInfo method.
In C# GC.Collect() "cleans up" the memory from unused/disposed objects.
For sure, there's no direct equivalent for that in Obj-C, but that may shed some light on your problem also (it could be memory-related).

keywindow is not working in ([[[UIApplication sharedApplication] keyWindow] addSubview:myView];) iOS 6

I am using below code to display a window over movie player controller:
[[[UIApplication sharedApplication] keyWindow] addSubview:myView];
Its working fine in iOS 5 but it stopped working in iOS 6. Even window is not displaying in iOS 6. So please can you suggest me the solution for this.
Thanks
Add [self.window makeKeyAndVisible] to your AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
method and you can use this code
[[[UIApplication sharedApplication] keyWindow] addSubview:view];
to your
- (void)viewDidAppear:(BOOL)animated
method in your ViewController
try this:
[[self window] makeKeyAndVisible];
[[[UIApplication sharedApplication] keyWindow] addSubview:view];
Try it after "appdidFinishLaunching:" finished! May solve it.
[[UIApplication sharedApplication] keyWindow] // available only on main thread

How to make status bar reappear after dismissing uiimagepickerviewcontroller

I am hiding the status bar in my application when I present my uiimagepickerviewcontroller modally.
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
In the callback method:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
I execute the following methods:
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];
before calling:
[picker dismissViewControllerAnimated:YES completion:^() {}];
I've tried "showing" the status bar in the completion block to no avail. How should I go about in getting the status bar to reappear after dismissing my uiimagepickerviewcontroller?
Try putting it back in the view controllers dismissal completion handler:
[picker dismissViewControllerAnimated:YES completion:^(BOOL done){
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];
}];
Although this is strange, there isn't any reason as to why this wouldn't be working jumping out at me.
I had the same problem in iOS 11. I could make the statusBar re-appear in the following way:
In Info.plist, set View controller-based status bar appearance to YES:
In the view controller that presents the UIImagePickerController, implement
- (BOOL)prefersStatusBarHidden {
return NO;
}

iPhone - Remove status bar programmatically

I have made an app that implements the iPhone's camera.
When the user finishes picking their image, the status bar reappears!
How would I make sure that the status bar stays hidden?
Here is my code:
-(IBAction)pickImage:(id)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[self presentModalViewController:picker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
background.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
}
If i am doing anything wrong, please point it out!
Thanks,
Rafee
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
You may opt for another animation style if at all.
In iOS 7, there is a method on UIViewController, "prefersStatusBarHidden". To hide the status bar, add this method to your view controller and return YES:
- (BOOL) prefersStatusBarHidden
{
return YES;
}
In this case,We are using 2 steps
In first step:
Add in info.plist: "View controller-based status bar appearance" with value "NO"
In Second step: Use/call this code with delegate of UIImagePickerController
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if([navigationController isKindOfClass:[UIImagePickerController class]])
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
With iOS 7 and later, you can use the following code to hide and unhide the status bar,
#interface ViewController()
#property (nonatomic, getter=isStatusBarHidden) BOOL statusBarHidden;
#end
#implementation ViewController
... other codes
- (BOOL)prefersStatusBarHidden {
return self.isStatusBarHidden;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationFade;
}
- (void)hideStatusBar {
self.statusBarHidden = YES;
[self setNeedsStatusBarAppearanceUpdate];
}
- (void)showStatusBar {
self.statusBarHidden = NO;
[self setNeedsStatusBarAppearanceUpdate];
}
#end
There seems to be a bug in the dismiss mechanism of UIViewController associated with UIImagePicker, with a sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum.
The moment of the call to dismissModalViewController (plus the method with completion:) the UIApplication's status bar hidden property instantly changes from YES to NO, and it is drawn at the moment of stepping over dismiss...
This is only really obvious for apps that use a full-screen view. My current app project does, plus I control the frame of the view controller's view before presenting, so the UIImagePicker is NOT full screen. This made the bug VERY obvious. I spent 4-5 hours determining the cause, and this was the final certain conclusion, and the bug does NOT occur for sourceType Camera nor PhotoLibrary.
So if you want a perfectly full-screen app and want to present a bug-free UIImagePicker, avoid UIImagePickerControllerSourceTypeSavedPhotosAlbum
Grand central dispatch is your friend, using this method you won't see the status bar appear at all when the picker is displayed or afterwards
- (void)hideStatusBar
{
if ([self respondsToSelector:#selector(setNeedsStatusBarAppearanceUpdate)])
{
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate)];
}
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self hideStatusBar];
double delayInSeconds = 0.2;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self hideStatusBar];
});
}

Disabled touch when UIProgressBarHUD is shown

I've created an app where I'm creating a UIProgressBarHUD to show that something is loading. My question is, how can I disable the view so nothing can be pressed untill the loading is finished?
I've tried setting:
[self.view setUserInterationEnabled:NO];
However this doesn't work :/
Here is the code I'm using for adding the UIProgressHUD:
- (IBAction) showHUD:(id)sender
{
//[self.view setUserInteractionEnabled:NO];
UIProgressHUD *HUD = [[UIProgressHUD alloc]
initWithWindow:[[UIApplication sharedApplication] keyWindow]];
[HUD setText:#"Loading…"];
[HUD show:YES];
[HUD performSelector:#selector(done) withObject:nil afterDelay:1.5];
[HUD performSelector:#selector(setText:) withObject:#"Done!"
afterDelay:1.5];
[HUD performSelector:#selector(hide) withObject:nil afterDelay:4.0];
//[self.view setUserInteractionEnabled:YES];
[HUD release];
}
Any help would be muchly appreciated!!
- James
You can disable user interaction with the nifty property named userInteractionsEnabled, that is defined for UIView. It just so happens that UIWindow is a subclass of UIView, we we can easily disable user interactions for out whole app.
anyViewInYouApp.window.userInteractionsEnabled = NO;
Or keep a reference to the window if you like.
In MBProgressHUD.m
#define APPDELEGATE
(TMAppDelegate *)[[UIApplication sharedApplication]delegate]
- (void)show:(BOOL)animated
{
[[APPDELEGATE window] setUserInteractionEnabled:NO]; //use this line
}
- (void)hide:(BOOL)animated
{
[[APPDELEGATE window] setUserInteractionEnabled:YES]; //use this line
}
As pointed out here, UIProgressHUD is private. You should not use it.
There is a library that gives you what you are looking for though.
It allows you to keep the user from tapping anything while it is updating as you requested.
UIWindow *win = [UIApplication sharedApplication].keyWindow;
[win setUserInteractionEnabled:NO];