禁用UI旋转时AVCaptureVideoPreviewLayer方向错误

Nik*_*een 9 objective-c rotation avfoundation ios avcapturesession

我有一个AVCaptureVideoPreviewLayer实例添加到视图控制器视图层次结构.

- (void) loadView {
   ...

   self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:nil];
   self.previewLayer.frame = self.view.bounds;
   self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

   [self.view.layer addSublayer: _previewLayer];

   // adding other UI elements
   ...
}

...

- (void) _setupPreviewLayerWithSession: (AVCaptureSession*) captureSession
{
   self.previewLayer.session = self.captureManager.captureSession;
   self.previewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
}
Run Code Online (Sandbox Code Playgroud)

图层框架在-viewDidLayoutSubviews方法中更新.视图控制器方向被锁定UIInterfaceOrientationMaskLandscapeRight.

问题如下:

  1. 该设备保持横向
  2. 视图控制器以模态方式呈现 - 视频层正确显示. 正确的方向
  3. 然后锁定设备并在锁定设备时将设备旋转到纵向.
  4. 然后,设备在仍然处于纵向方向时被解锁,并且几秒钟后,视频层被显示为旋转90度.但是,视频层的帧是正确的.所有其他UI元素都正确显示.几秒钟后,图层会捕捉到正确的方向.请在下面找到图层和UI元素的边界 方向不正确

我尝试将视频图层方向更新为以下(没有结果):

  • 订阅AVCaptureSessionDidStartRunningNotificationUIApplicationDidBecomeActiveNotification通知
  • 调用-viewWillTransitionToSize:withTransitionCoordinator:方法时调用更新
  • -viewWillAppear:

该问题似乎与视频层方向本身无关,而是与查看层次结构布局有关.

更新:

正如所建议的那样,我也尝试更新设备方向更改的视频图层方向,但没有帮助.

我还注意到,问题主要发生在应用程序启动后,屏幕首次出现.在同一会话期间的后续屏幕演示中,问题的重现率非常低(类似于1/20).

Sar*_*gis 3

试试这个代码:

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(orientationChanged:)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];
-(void)orientationChanged:(NSNotification *)notif {

    [_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
    if (_videoPreviewLayer.connection.supportsVideoOrientation) {
        _videoPreviewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation:[UIApplication sharedApplication].statusBarOrientation];
    }

}

- (AVCaptureVideoOrientation)interfaceOrientationToVideoOrientation:(UIInterfaceOrientation)orientation {
    switch (orientation) {
        case UIInterfaceOrientationPortrait:
            return AVCaptureVideoOrientationPortrait;
        case UIInterfaceOrientationPortraitUpsideDown:
            return AVCaptureVideoOrientationPortraitUpsideDown;
        case UIInterfaceOrientationLandscapeLeft:
            return AVCaptureVideoOrientationLandscapeLeft;
        case UIInterfaceOrientationLandscapeRight:
            return AVCaptureVideoOrientationLandscapeRight;
        default:
            break;
    }
//    NSLog(@"Warning - Didn't recognise interface orientation (%d)",orientation);
    return AVCaptureVideoOrientationPortrait;
}
Run Code Online (Sandbox Code Playgroud)