当前位置: 首页 > 知识库问答 >
问题:

防止带有AVCaptureVideoPreviewLayer的UIView与ViewController的其余部分一起旋转

松雅健
2023-03-14

我有一个嵌入在选项卡栏控制器中的视图控制器,它在UIView中显示一个AVCaptureVideoPreviewLayer。

当设备旋转时,我希望视图控制器随之旋转——除了前面提到的UIView。

然而,与这个相关的问题不同,我不只是在视图控制器中旋转/转换我的其他视图。其他视图需要使用它们配置的自动布局旋转行为。

我尝试了几种方法,包括简单地将视频方向设置为纵向:

previewLayer.connection.videoOrientation = .portrait

将UIView提取到单独的视图控制器,将该视图控制器嵌入到原始视图控制器中,并设置其自动旋转属性

override var shouldAutorotate: Bool {
    return false
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

但后来我在这里了解到,iOS只查看这些属性的顶级视图控制器。

无论我做了什么尝试,视频预览都会随着视图控制器的其余部分一起旋转,最终会横向结束。

唯一的工作原理,但有时会导致视频预览变得不对齐,就是这个

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        if let videoPreviewLayerConnection = previewLayer.connection {
            if let newVideoOrientation = AVCaptureVideoOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue) {
                videoPreviewLayerConnection.videoOrientation = newVideoOrientation
            }
        }
    }
}

我基本上需要这个问题的反面。

如何强制视频预览不旋转,但允许视图控制器的其余部分正常旋转?(与iOS摄像头应用程序的行为相同,只是其他UI元素正常旋转,而不是90°旋转变换)

共有1个答案

阎咏思
2023-03-14

以下内容可能与您的解决方案一样粗鲁,但在视觉上看起来更干净。

在视图WillTransition中,我设置了previewView的仿射变换,以抵消旋转手机设置的方向。它看起来比仅仅设置视频方向更清晰,因为仿射变换的动画速度与方向更改的速度相同。具体操作如下。

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    let orientation = UIDevice.current.orientation
    var rotation : CGFloat = self.previewView.transform.rotation
    switch(orientation) {
    case .portrait:
        rotation = 0.0
    case .portraitUpsideDown:
        rotation = CGFloat.pi
    case .landscapeLeft:
        rotation = -CGFloat.pi/2.0
    case .landscapeRight:
        rotation = CGFloat.pi/2.0
    default:
        break
    }
    let xScale = self.previewView.transform.xScale
    let yScale = self.previewView.transform.yScale
    self.previewView.transform = CGAffineTransform(scaleX:xScale, y:yScale).rotated(by:rotation)
    self.view.layoutIfNeeded()

}

下面是上述代码使用的CGAffineTransform的扩展

extension CGAffineTransform {
    public var xScale: CGFloat {
        get {return sqrt(self.a * self.a + self.c * self.c) }
    }
    public var yScale: CGFloat {
        get {return sqrt(self.b * self.b + self.d * self.d) }
    }
    public var rotation: CGFloat {
        get {return CGFloat(atan2f(Float(self.b), Float(self.a))) }
    }
}
 类似资料:
  • 问题内容: 我有以下SQL: 在Oracle SQL Developer 4.0.0.13(连接到DB2数据库)中,我在以下斜体下面显示了 一条弯曲的 行:“ from pluspbillline ”和“ left external join workorder ”。 警告说:“ pluspbillline已与连接图的其余部分断开连接”。这是什么意思? 问题答案: 我不确定是什么原因导致Oracl

  • 问题内容: 我正在尝试旋转一个视图,而所有其他视图(5)都固定为纵向。原因是在该视图中,我希望用户观看以前保存的图片。我想这是可能的,但到目前为止我还不知道如何实现。谁能帮忙或给我提示吗?我正在在iOS8上运行的Swift中编程 问题答案: 这是针对 Swift 3和Swift 4的 。您可以在AppDelegate.swift中使用以下代码: 您可以在原始帖子中了解更多信息:http : //w

  • 我试图旋转一个视图,而所有其他视图(5)都固定为纵向。原因是,在这一视图中,我希望用户观看他之前保存的图片。我想这是可能的,但到目前为止我还不知道如何做到这一点。有谁能帮我或给我一个提示吗?我正在用iOS8上的Swift进行编程

  • 问题内容: 我正在使用Jsoup清理来自表单的用户输入。有问题的表单包含一个要求纯文本的表单。提交表单后,我使用; 清除输入。但是,由于html会忽略多余的空格,因此将从输入中删除有价值的空格字符。 例如,如果有人在中输入了一些文本行: 之后,您将拥有: 如何使保留空白?我知道它是为解析html而设计的,而不是html,因此还有更好的选择吗? 问题答案: 如果您的textarea只希望使用纯文本,

  • 本文向大家介绍clojure 将序列的其余部分转换为图,包括了clojure 将序列的其余部分转换为图的使用技巧和注意事项,需要的朋友参考一下 示例 解构还使您能够将序列解释为图: 这对于使用命名参数定义函数很有用:            

  • 我有一个应用程序,我想添加一个管理页面。我希望管理页面有自己的布局从客户端布局分开。以我现有的情况来看,实现这一目标的当前“最佳”方式是什么? app.js HOC 我找到了这个。我应该创建一个和组件并过滤页面吗?