5

I'm trying to use AVCaptureVideoPreviewLayer to get the camera to display in landscape mode, but no matter what I do, the camera always shows up on only half of the screen in landscape mode.

I have it so my app only supports Landscape Right, and the view orientation is clearly Landscape Right when the app starts up, but when I set the frame of the Video Preview Layer to the bounds of the view, it's as if it's still in Portrait mode. If I log the width and height of the view, it prints 320x568 instead of 568x320.

I have searched and looked at every thread and guide that pertains to what I'm trying to do, and haven't found a solution that works on any of them.

Here's my code (in viewDidLoad):

    // Create video preview layer and add it to the UI
    self.videoLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureManager.captureSession];

    [[self.view layer] setMasksToBounds:YES];

    self.videoLayer.frame = self.view.bounds;

    if(self.videoLayer.connection.supportsVideoOrientation)
    {
        self.videoLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
    }

    [self.videoLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

    [self.view.layer addSublayer:self.videoLayer];

    [self.captureManager.captureSession startRunning];

The above code results in this on my device: https://i.stack.imgur.com/xUXfO.jpg

Any help would be greatly appreciated.

EDIT:

So I came up with a solution of sorts. I don't know if there is a way to work around this, but it's the only way I can think of to make it so there's no delay before the camera appears. I basically just made a new CGRect with the flipped width and height of the view.

Here's the fixed code:

    // Create video preview layer and add it to the UI
    self.videoLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureManager.captureSession];

    [self.view.layer setMasksToBounds:YES];

    CGSize landscapeSize;
    landscapeSize.width = self.view.bounds.size.height;
    landscapeSize.height = self.view.bounds.size.width;

    CGRect landscapeRect;
    landscapeRect.size = landscapeSize;
    landscapeRect.origin = self.view.bounds.origin;

    self.videoLayer.frame = landscapeRect;

    //NSLog(@"%f, %f", self.view.frame.size.width, self.view.frame.size.height);

    if(self.videoLayer.connection.supportsVideoOrientation)
    {
        self.videoLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
    }

    [self.videoLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

    [self.view.layer addSublayer:self.videoLayer];

    [self.captureManager.captureSession startRunning];
ryanthon
  • 2,524
  • 3
  • 17
  • 18
  • 1
    you should add self.videoLayer in viewDidappear or you should add afterDelay 0.3 – Sunny Shah Aug 22 '13 at 04:47
  • Yeah I know I can use viewDidAppear, but there would be a small delay with a white screen showing before the camera appears. I came up with a way for no delay in my edit though. – ryanthon Aug 22 '13 at 05:19
  • CGRect rect=[[UIScreen mainScreen]bounds]; check rect gives perfect frane – Sunny Shah Aug 22 '13 at 05:24

0 Answers0