Using UIImagePickerController in landscape orientation - ios

I am creating an app which is in landscape mode and I am using UIImagePickerController to take photos using iPhone camera in it and I want to create it in landscape mode too.
But as the Apple documention suggests UIImagePickerController does not support landscape orientation, so what should I do to get desired functionality?

If you'd like to use UIImagePickerController in landscape mode, use user1673099's answer, but instead of:
- (BOOL)shouldAutorotate
{
return NO;
}
use:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
and then the picker would open in landscape mode:
But make sure you check Portrait in deployment info:

... and I want to create it in landscape mode too.
One line of code can make a big difference! In the method or function where your IBAction lands:
In Swift,
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
// .overCurrentContext allows for landscape and portrait mode
imagePickerController.modalPresentationStyle = .overCurrentContext
Objective-C,
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
[imagePickerController setDelegate:self];
[imagePickerController setModalPresentationStyle: UIModalPresentationOverCurrentContext];
Note: This will allow imagePickerController to present it's view correctly, but will may not fix the issue of rotation while it is presented.

Try this way....
As per Apple Document, ImagePicker Controller never Rotate in Landscape mode. You have to use in Portrait Mode only.
For disable Landscape mode only for ImagePicker Controller follow below code:
In your ViewController.m:
Make the SubClass(NonRotatingUIImagePickerController) of Image Picker Controller
#interface NonRotatingUIImagePickerController : UIImagePickerController
#end
#implementation NonRotatingUIImagePickerController
// Disable Landscape mode.
- (BOOL)shouldAutorotate
{
return NO;
}
#end
Use as follow
UIImagePickerController* picker = [[NonRotatingUIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
etc.... Just as Default ImagePicker Controller
This is working for me & Let me know if you have any Problem.

This works great with Swift 4.0 in iOS 10/11.
import UIKit
extension UIImagePickerController {
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .all
}
}
Just drop the extension somewhere in your project, no need to subclass anything for it to work.
If you do need to specify device types, you can add a check like this:
import UIKit
extension UIImagePickerController {
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all
}
}
This will allow an iPad to freely rotate, but enforces portrait mode on a phone. Just make sure that your app is configured to support these in its info.plist, otherwise you may encounter crashes upon launching the picker.

Here's a version that supports rotation in all interface orientations:
/// Not fully supported by Apple, but works as of iOS 11.
class RotatableUIImagePickerController: UIImagePickerController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .all
}
}
This way if the user rotates her device, it'll update the picker controller to support the current orientation. Just instantiate as you normally would a UIImagePickerController.
If you only want to support a subset of orientations, you can return a different value.

The correct way to use UIImagePickerController in landscape mode without any hacks is to put it into a UIPopoverController
- (void)showPicker:(id)sender
{
UIButton *button = (UIButton *)sender;
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
_popover = [[UIPopoverController alloc] initWithContentViewController:picker];
[_popover presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}

Modify above code method
- (NSUInteger)supportedInterfaceOrientations
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if(orientation == UIDeviceOrientationLandscapeRight || orientation == UIDeviceOrientationLandscapeLeft)
return UIInterfaceOrientationMaskLandscape;
else
return UIInterfaceOrientationMaskPortrait;
}

Accepted answer doesn't work for me. I had also to add modalPresentationStyle to UIImagePickerController to make it working.
UIImagePickerController *pickerController = [[UIImagePickerController alloc] init];
pickerController.modalPresentationStyle = UIModalPresentationCurrentContext; //this will allow the picker to be presented in landscape
pickerController.delegate = self;
pickerController.allowsEditing = YES;
pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:pickerController animated:YES completion:nil];
And of course remember to put this in a controller that presents the picker:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape; //this will force landscape
}
But according to Apple's documentation this is not supported to present this picker in the landscape mode so be careful about it.

If you're looking for SwiftUI solution in conjunction with the things mentioned here check this out here. Ignoring the safe area for the UIImagePickerController representable resolved a lot of my issues.

Related

iOS 11 UIImagePickerController strange issue

I am using UIImagePickerController to select a single image from photo library. There is a strange issue on iPad when it is in landscape mode.
The image picker is presented using UIPopoverPresentationController on iPad as recommended. When it is first presented, the status bar is correct:
However, when going into the second level of the photo library, the status bar is changed to portrait mode:
What I have noticed so far are:
This issue only appears in iOS 11, not iOS 10.
When it happens, rotate the iPad to portrait and back to landscape will fix the status bar orientation.
It only happened the first time presenting the picker controller.
If ignore, presenting other modal view will be in portrait mode:
The code that presenting the uiimagepickerController is as follow:
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.modalPresentationStyle = UIModalPresentationPopover;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];
UIPopoverPresentationController *popupController = picker.popoverPresentationController;
if (popupController) {
popupController.barButtonItem = sender;
}
Any idea what have I done wrong, or it is a bug?
Whole example project can be downloaded here:
https://www.dropbox.com/s/zgipclyr0mz26c6/test.zip?dl=0
I have finally found the cause of my issue.
My app needs to support all orientation on iPad and Portrait mode only on iPhone. Therefore I added the following code of UIApplicationDelegate:
- (UIInterfaceOrientationMask) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if (window.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
But sometimes it gives me nil window, as in the case of UIImagePickerController presented using UIPopoverPresentationController on iPad, and will return UIInterfaceOrientationMaskPortrait and cause the status bar rotates to portrait mode. I have also noticed that this happens only when UIRequiresFullScreen is checked.
I have solved my issue by checking that window is not nil as below:
- (UIInterfaceOrientationMask) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if (window) {
if (window.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
return UIInterfaceOrientationMaskAll;
} else {
return UIInterfaceOrientationMaskPortrait;
}
} else {
return UIInterfaceOrientationMaskAll;
}
}

Landscape only iPad app displays UIImagePicker in portrait orientation

I have an iPad app that only supports landscape orientations, however when I try to display a UIImagePickerController inside a UIPopoverController it always appears in portrait mode. i.e. rotated 90 degrees from the rest of the UI. Does anyone know how I can make this appear in the same orientation as the ViewController I'm presenting it in?
I'm displaying the imagePicker like this:
self.picker = [[FFSImagePicker alloc] init];
picker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
picker.delegate = self;
picker.toolbarHidden = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.allowsEditing = NO;
picker.showsCameraControls = YES;
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:picker];
self.photoPickerPopover = popover;
[self.photoPickerPopover presentPopoverFromRect:photoButton.bounds inView:photoButton permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
FFSImagePicker is just a subclass of UIImagePickerController where I tried to make sure the supported orientations were only landscape, but that had no effect.
Thanks for any help...
OK, I solved this, the issue was that I was presenting the UIImagePickerController in a UIPopover which Apple says not to do when the source type is the camera, instead present it full screen just like you would any other view controller.
Hope this helps someone else too...

use UIImagePickerController in landscape mode app in iOS

is it possible to use UIImagePickerController to fetch image from gallery without making whole app in portrait mode in iOS .Thanks
Create a custom class of UIImagePickerController. Override supportedInterfaceOrientations meted
- (NSUInteger) supportedInterfaceOrientations
{
//Because your app is only landscape, your view controller for the view in your
// popover needs to support only landscape
return UIInterfaceOrientationMaskAll;
}
-(BOOL)shouldAutorotate{
return yes;
}
//call custom view like this
CustomImagePickerViewController *picker = [[CustomImagePickerViewController alloc] init];
picker.supportedInterfaceOrientations= UIInterfaceOrientationMaskAll;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];

Landscape orientation image picker.

I'm creating an app that is landscape only, it uses an image picker control.
Looking through the site I've discovered that apple only allow portrait for this for some reason. I'm okay with it flipping to portrait for this one section, if it means the user can select a photo from the library.
Below is my code that gives an error about it being in landscape mode. How do I fix this to say it's okay to flip it to portrait. thanks
-(IBAction)takePhoto{
takePicker = [[UIImagePickerController alloc]init];
takePicker.delegate = self;
[takePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentViewController:takePicker animated:YES completion:NULL];
}
-(IBAction)chooseExisiting{
choosePicker = [[UIImagePickerController alloc]init];
choosePicker.delegate = self;
[choosePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:choosePicker animated:YES completion:NULL];
}
You don't have to use ImagePickerController in portrait mode.
Just subclass it to open in landscape mode :
#interface NonRotatingUIImagePickerController : UIImagePickerController
#end
#implementation NonRotatingUIImagePickerController
- (BOOL)shouldAutorotate
{
return NO;
}
#end
After that, you can use your code with that class.
-(IBAction)takePhoto {
takePicker = [[NonRotatingUIImagePickerController alloc]init];
takePicker.delegate = self;
[takePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentViewController:takePicker animated:YES completion:NULL];
}
-(IBAction)chooseExisiting{
choosePicker = [[NonRotatingUIImagePickerController alloc]init];
choosePicker.delegate = self;
[choosePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:choosePicker animated:YES completion:NULL];
}
Why present an error at all? Why not just present the image picker in portrait? People are smart enough to rotate their device. Or you could write your own landscape image picker, or use one of the several open source ones available.

lock UIImagePickerController in Portrait mode in ios app

In my IOS app, when I open the camera I have placed an image over the camera view. It looks good in portrait mode. But when it is changed to landscape mode it looks some odd. So I want to lock the UIImagePickerController in Portrait mode.
Following is my code for ui image picker controller
UIImagePickerController *imgPkr = [[UIImagePickerController alloc] init];
imgPkr.delegate = self;
imgPkr.sourceType = UIImagePickerControllerSourceTypeCamera;
How it can be locked in portrait mode....
Or, you can subclass the UIImagePickerController:
Create a new UIImagePickerController class and just add these lines to it.
- (BOOL)shouldAutorotate{
return NO;
}
Import it to the class that uses the camera and instead of using default UIImagePickerController, use the class that you created.
Your camera itself should stop from auto rotating.
This is not the best solution, but it works:
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
[appDelegate.window addSubview:cameraOverlay];
imgPicker.cameraOverlayView = appDelegate.window.superview;
The camera on the background still rotates, but your overlay view doesn´t.
Hope it works for you
The only solution that worked for me was the category, but I had to add another method too:
#import "UIImagePickerController+NoRotate.h"
#implementation UIImagePickerController (NoRotate)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
#end
Cheers!
You don't have to "lock the UIImagePicker Controller in Portrait mode".
As you said "when it is changed to landscape mode it looks some odd"
Actually I don't know why you say it look odd.
But, here is my experience of UIImagePicker view look odd in landscape mode.
That is:
When AViewController as the root view controller.
And BViewController's view add subview to AViewController's view.
And presentModalViewController:UIImagePickerController in BViewController.
The UIImagePicker view will look odd in landscape mode.
The solution to this problem is set the UIImagePickerController as the root view controller before presentModelViewController.
The source code below show the detail:
- (void) onCameraButtonTapped:(UIBarButtonItem *)buttonItem
{
//backupRootController it's use as a backup, it will recover after close the image picker controller.
self.backupRootController = [[UIApplication sharedApplication] keyWindow].rootViewController;
UIImagePickerController * imageController = [[UIImagePickerController alloc] init];
imageController.sourceType = UIImagePickerControllerSourceTypeCamera;
imageController.delegate = self;
....
[[[UIApplication sharedApplication] keyWindow] setRootViewController:imageController];
[self presentModalViewController:imageController animated:YES];
[imageController release];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[[[UIApplication sharedApplication] keyWindow] setRootViewController:self.backupRootController];
....
}
I hope this solution can help other person in the future.
--Goman
Add a category on UIImagePickerController and override it's shouldAutoRotateToInterfaceOrientation method, as follows:
#implementation UIImagePickerController (NoRotate)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Just write this code in your view controller
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate {
return NO;}
Try this in your view controller. This worked for me.
Note: This is for ios6.0 and above
there is no need to create a subclass, just create a category for uiimagepickercontroller and put this line on it
- (BOOL)shouldAutorotate{
return NO;
}

Resources