如何解决AVCaptureVideoPreviewLayer预览无法随设备旋转的问题
问题根因
AVCaptureVideoPreviewLayer 的预览方向是独立管控的,和 App 界面的旋转配置不互通。你只配置了 ViewController 支持所有方向旋转,没有同步调整预览层的输出方向,所以会出现横屏时画面侧转的问题。
修复方案
- 在界面方向变化的回调中,同步更新预览层关联连接的视频输出方向即可,推荐使用
viewWillTransition系统回调监听方向变化,无需额外加通知监听。 - 注意:不要直接对
UIInterfaceOrientation和AVCaptureVideoOrientation做枚举强转,两者的landscapeLeft/landscapeRight枚举值是反向对应的,直接赋值会导致横屏方向颠倒
代码示例
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .all } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) // 此处 previewLayer 为你项目中定义的 AVCaptureVideoPreviewLayer 实例 guard let connection = previewLayer.connection, let windowScene = view.window?.windowScene else { return } let interfaceOrientation = windowScene.interfaceOrientation let targetOrientation: AVCaptureVideoOrientation switch interfaceOrientation { case .portrait: targetOrientation = .portrait case .portraitUpsideDown: targetOrientation = .portraitUpsideDown case .landscapeLeft: targetOrientation = .landscapeLeft case .landscapeRight: targetOrientation = .landscapeRight default: targetOrientation = .portrait } connection.videoOrientation = targetOrientation // 同步更新预览层尺寸适配当前界面大小 previewLayer.frame = view.bounds }
适配注意事项
- 如果你的 App 需要兼容 iOS 15 及更低版本,获取当前界面方向的代码替换为
UIApplication.shared.statusBarOrientation即可 - 相机初始化完成后需要手动设置一次初始的
videoOrientation,避免首次进入横屏页面时方向不匹配 - 可根据业务需求调整
previewLayer.videoGravity为.resizeAspectFill/.resizeAspect控制预览画面的填充规则,避免拉伸变形
内容的提问来源于stack exchange,提问作者Marin
相关产品推荐
相关产品推荐

