1

I am currently developing an application to record and edit videos. The hole application supports only landscape mode - so I would like to use the camera controls in landscape to. But the preview screen always switches back to portrait. A similar question was asked before (camera preview is portrait in landscape app) but sadly without any accepted answer.

I tried several approaches:

First I added the view of the UIImagePickerController manually - the preview was exactly as I want it to be, but the video image (while recording) was wrong (turned sideways).

code:

- (BOOL) startCameraController {
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO) {
        return NO;
    }

    self.cameraUI = [[UIImagePickerController alloc] init];
    self.cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
    self.cameraUI.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
    self.cameraUI.allowsEditing = NO;
    self.cameraUI.delegate = self.parentViewController;

    [self.parentViewController addChildViewController:self.cameraUI];
    self.cameraUI.view.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    [self.parentViewController.view addSubview:self.cameraUI.view];

    return YES;
}

result:

The preview is displayed in the correct orientation, but the camera image is turned sideways.

Then I used presentViewController to show the UIImagePickerController - the camera recording works perfectly fine, but the preview screen is in portrait and I have to turn my device to work with it.

code:

- (BOOL) startCameraController {
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO) {
        return NO;
    }

    self.cameraUI = [[UIImagePickerController alloc] init];
    self.cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
    self.cameraUI.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
    self.cameraUI.allowsEditing = NO;
    self.cameraUI.delegate = self.parentViewController;

    [self.parentViewController presentViewController:self.cameraUI animated:YES completion:^{}];

    return YES;
}

result:

The preview screen is turned upside down, so that I have to turn my device to use the controls.

I even listend to the event _UIImagePickerControllerUserDidCaptureItem to detect when the camera changed to preview and tried to manually turn the view - but I wasn't able to adapt the frame dimensions of the preview view.

code:

- (void) cameraChangedToPreview {
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];

    if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationLandscapeRight) {
        self.cameraUI.view.transform = CGAffineTransformMakeRotation(M_PI_2);
    } else if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationLandscapeLeft) {
        self.cameraUI.view.transform = CGAffineTransformMakeRotation(-M_PI_2);
    }

    if (IS_WIDESCREEN) {
        self.cameraUI.view.frame = CGRectMake(0, 0, 568, 320);
    } else {
        self.cameraUI.view.frame = CGRectMake(0, 0, 480, 320);
    }
}

result: The screen dimensions of the preview are wrong.

I would be really grateful for any hints or suggestions how I could use camera and preview in landscape mode, so that I can use my hole application without turning the device in the process (The device will be in a tripod while the application is used, so it can't be turned.)

Thank you and best wishes!

Community
  • 1
  • 1
appsperimental
  • 297
  • 2
  • 8

2 Answers2

0

UIImage Picker View Cannot be Used only in LandScape mode here is what apple says about it

mportant: The UIImagePickerController class supports portrait mode only. This class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified, with one exception. You can assign a custom view to the cameraOverlayView property and use that view to present additional information or manage the interactions between the camera interface and your code.

you can read more about it from here https://developer.apple.com/library/ios/documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html#//apple_ref/doc/uid/TP40007070-CH3-DontLinkElementID_1

Geet
  • 2,427
  • 2
  • 21
  • 39
0

You can show the view controller as modal, lock rotation to portrait and then listen to motion sensor and detect rotation from there. Something like this:

self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.accelerometerUpdateInterval = 0.5f;
[self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
                                         withHandler:^(CMAccelerometerData  *accelerometerData, NSError *error) {
                                             float x = -accelerometerData.acceleration.x;
                                             float y = accelerometerData.acceleration.y;
                                             float angle = atan2(y, x);

                                             if(angle >= -2.25 && angle <= -0.75) {
                                                 currentOrientation = UIInterfaceOrientationPortrait;
                                             } else if(angle >= -0.75 && angle <= 0.75){
                                                 currentOrientation = UIInterfaceOrientationLandscapeRight;
                                             } else if(angle >= 0.75 && angle <= 2.25) {
                                                 currentOrientation = UIInterfaceOrientationPortraitUpsideDown;
                                             } else if(angle <= -2.25 || angle >= 2.25) {
                                                 currentOrientation = UIInterfaceOrientationLandscapeLeft;
                                             }
                                         }];

Afterwards you can use the currentOrientation to properly rotate the image before saving with:

[videoConnection setVideoOrientation:currentOrientation];

Hope this helps you