32

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?

iain
  • 5,660
  • 1
  • 30
  • 51
Paras Gorasiya
  • 1,295
  • 2
  • 13
  • 33
  • It seems to work in iOS 8 beta 4. The only problem is after taking the photo it will show you the screen (use this photo or cancel) in portrait mode. But image captured fine in landscape. – Lim Thye Chean Jul 29 '14 at 09:59

9 Answers9

47

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:

enter image description here

But make sure you check Portrait in deployment info:

enter image description here

Community
  • 1
  • 1
iOS.Lover
  • 5,923
  • 21
  • 90
  • 162
  • It works great. One question, why should we check Portrait in deployment info? I know it is necessary but I cannot understand the reason. – Anson Yao Dec 30 '14 at 07:04
  • 2
    @AnsonYao because `UIImagePickerController` only supports Portrait mode. If you don't support portrait "globally" the image picker will crash as it has no usable orientations. – pkamb Mar 03 '15 at 00:32
  • @Mc.Lover its working if i check Portrait mode in deployment info. but it just changes my whole application's orientation. would you please tell me how can i solve this issue – shaqir saiyed Dec 19 '15 at 11:26
  • @shaqirsaiyed add : override func shouldAutorotate() -> Bool { if (UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft || UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight){ return true } else { return false; } } override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { return [UIInterfaceOrientationMask.Landscape] } To any view controllers that should only be in Landscape. – vtcajones Jan 28 '16 at 05:46
  • That's swift, but you get the idea. – vtcajones Jan 28 '16 at 05:47
  • Yes i extend UIImagePicker class and add this method as mentioned Thankxx :) – Abhishek Thapliyal Jul 30 '16 at 11:44
  • For some reason, I get significant stuttering when scrolling through the gallery on my iPad 2 using this approach. – Carl Smith Aug 18 '16 at 20:21
  • Additionally, if you want to support portrait and landscape use the mask: UIInterfaceOrientationMaskAllButUpsideDown – Matt__C Jun 05 '17 at 18:21
34

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

David
  • 3,285
  • 1
  • 37
  • 54
  • 1
    This should be the accepted answer. No subclassing, overriding in extensions or any other hacks, just plain and simple public APIs. – Nicolas Miari Sep 30 '18 at 02:45
14

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.

Raptor
  • 53,206
  • 45
  • 230
  • 366
user1673099
  • 3,293
  • 7
  • 26
  • 57
9

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.

CodeBender
  • 35,668
  • 12
  • 125
  • 132
6

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.

Senseful
  • 86,719
  • 67
  • 308
  • 465
5

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];
}
iain
  • 5,660
  • 1
  • 30
  • 51
3

Modify above code method

- (NSUInteger)supportedInterfaceOrientations
 {
     UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
     if(orientation == UIDeviceOrientationLandscapeRight || orientation == UIDeviceOrientationLandscapeLeft)
         return UIInterfaceOrientationMaskLandscape;
     else
         return UIInterfaceOrientationMaskPortrait;
 }
Abhishek Thapliyal
  • 3,497
  • 6
  • 30
  • 69
2

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.

Michal Cichon
  • 1,409
  • 14
  • 19
  • how you can implement supportedInterfaceOrientations under the delegate ? – zeus Jul 13 '18 at 19:15
  • To be more precise: the view controller that presents `UIImagePickerController` should have `supportedInterfaceOrientations`. In my example, a delegate is a controller that presents the picker. I will update my answer. – Michal Cichon Jul 14 '18 at 10:07
2

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.

telaCode
  • 159
  • 11