Using UIImagePickerController in landscape orientation
Asked Answered
B

9

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?

Bogosian answered 15/10, 2013 at 6:1 Comment(1)
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.Quincuncial
G
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

Gypsie answered 28/10, 2013 at 9:14 Comment(8)
It works great. One question, why should we check Portrait in deployment info? I know it is necessary but I cannot understand the reason.Willenewillet
@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.Sinclare
@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 issueSusannesusceptibility
@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.Cano
That's swift, but you get the idea.Cano
Yes i extend UIImagePicker class and add this method as mentioned Thankxx :)Typecase
For some reason, I get significant stuttering when scrolling through the gallery on my iPad 2 using this approach.Nadda
Additionally, if you want to support portrait and landscape use the mask: UIInterfaceOrientationMaskAllButUpsideDownRuck
J
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.

Jolt answered 28/2, 2017 at 17:59 Comment(1)
This should be the accepted answer. No subclassing, overriding in extensions or any other hacks, just plain and simple public APIs.Hyphenated
A
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.

Atalanti answered 15/10, 2013 at 6:9 Comment(3)
Is this helpful to you??Atalanti
I don't want to disable landscape mode, I only want to use image picker controller in landscape mode not in portraite mode. I want to know if i can rotate image picker for taking pictures as well or not ??Bogosian
@ParasGorasiya, ImagePicker will never support the Landscape Mode. It only support the Portrait Mode.Atalanti
G
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.

Game answered 26/10, 2017 at 22:41 Comment(0)
B
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.

Bitstock answered 26/10, 2017 at 20:9 Comment(0)
R
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];
}
Rumpf answered 28/7, 2014 at 11:48 Comment(7)
Only applicable in UIUserInterfaceIdiomPadTextuary
@iTroyd23 It can be hacked by adding category to UIPopoverControllerBugleweed
@Bugleweed Right, so you replace one hack with another? ;-)Lachrymal
My hack it's just simpler to use :)Bugleweed
This works nicely with UIPopoverPresentationController in iOS 8 and 9 with iPad, but on iPhone it fails the second time (but not the first). So bizarre...Playacting
Check out my answer here for another option: https://mcmap.net/q/453817/-set-shouldautorotate-to-false-with-photolibraryPlayacting
A UIPopoverController is a very different UI than the native UIImagePickerController.Nadda
T
3

Modify above code method

- (NSUInteger)supportedInterfaceOrientations
 {
     UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
     if(orientation == UIDeviceOrientationLandscapeRight || orientation == UIDeviceOrientationLandscapeLeft)
         return UIInterfaceOrientationMaskLandscape;
     else
         return UIInterfaceOrientationMaskPortrait;
 }
Typecase answered 30/7, 2016 at 12:6 Comment(0)
C
3

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.

Contentious answered 5/10, 2021 at 17:38 Comment(1)
Thank you! This was the only thing that worked for me. :)Cullet
A
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.

Apish answered 2/12, 2016 at 8:30 Comment(2)
how you can implement supportedInterfaceOrientations under the delegate ?Noise
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.Apish

© 2022 - 2024 — McMap. All rights reserved.