【问题标题】:AVCaptureVideoPreviewLayer wrong orientation when UI rotation is disabled禁用 UI 旋转时 AVCaptureVideoPreviewLayer 方向错误
【发布时间】:2017-09-25 07:35:15
【问题描述】:

我有一个 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;
}

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

问题如下:

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

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

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

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

更新:

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

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

【问题讨论】:

  • 注册 enterForeground 通知,添加 func fixOrientation() 在 vi​​ewWillAppear 和 enterForeground 上调用它,在方法中: UIDevice.current.setValue(NSNumber(value: UIInterfaceOrientation.portrait.rawValue), forKey: "方向”)你需要弄清楚它的横向/右侧,几年前我在 Obj-c 中使用过这段代码,所以写成评论,因为我还没有测试过

标签: ios objective-c rotation avfoundation avcapturesession


【解决方案1】:

试试这个代码:

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

【讨论】:

  • 谢谢,我已尝试实施您的建议,但也没有用。有关更多信息,请参阅问题中的更新部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
相关资源
最近更新 更多