ios - 禁用 UI 旋转时 AVCaptureVideoPreviewLayer 方向错误

标签 ios objective-c rotation avfoundation avcapturesession

我有一个 AVCaptureVideoPreviewLayer 实例添加到 View Controller View 层次结构中。

- (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;
}

层框架在 -viewDidLayoutSubviews 方法中更新。 View Controller 方向锁定为 UIInterfaceOrientationMaskLandscapeRight

问题如下:

  1. 设备横向放置
  2. View Controller 以模态方式呈现 - 视频层正确显示。 Correct orientation
  3. 然后设备被锁定,并且在锁定期间设备旋转到纵向。
  4. 然后解锁设备同时仍处于纵向并且视频层旋转 90 度显示几秒钟。但是,视频层的帧是正确的。所有其他 UI 元素都正确显示。几秒钟后,图层会捕捉到正确的方向。 请在下面找到层和 UI 元素的边界 Incorrect orientation

我试过如下更新视频层方向(没有结果):

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

这个问题似乎与视频层方向本身无关,而更多地与 View 层次结构布局有关。

更新:

按照建议,我还尝试在设备方向更改时更新视频层方向,但没有帮助。

我还注意到这个问题主要发生在应用程序启动并首次显示屏幕之后。在同一 session 的后续屏幕演示中,问题的重现率非常低(大约 1/20)。

最佳答案

试试这段代码:

[[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;
}

关于ios - 禁用 UI 旋转时 AVCaptureVideoPreviewLayer 方向错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43658923/

相关文章:

ios - 自定义警报 View 的验证

iphone - 如何在文档目录的子文件夹中创建文件?

ios - removeObserver with NSNotification...我做错了什么?

iphone - 如何安全地重命名 iOS 分发配置文件?

iOS 11 核心蓝牙 : Cannot remove an observer CBPeripheral for the key path "delegate"

ios - iTunes RSS Feed 总是返回 duration=30000

objective-c - Xcode 8 Autocomplete Broken - 仅显示有限的用户代码片段 - 知道为什么吗?

text - 如何使用 Java2D 使旋转文本看起来不错

javascript - 如何在 html 5 Canvas 上的圆圈内旋转图片?

Android 在 API 级别 >= 8 中旋转 TextView