Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top