我在Swift中使用AVFoundation
通常,当我设置摄像机捕获会话时,我会在objective-c
中执行以下操作[[cameraView.previewLayer connection] setVideoOrientation:(AVCaptureVideoOrientation)[self interfaceOrientation]]
在swift中,似乎我必须做这样的事情(因为可选类型)
if let connection = cameraView.previewLayer?.connection {
connection.videoOrientation = self.interfaceOrientation as AVCaptureVideoOrientation
}
然而,这抱怨
‘AVCaptureVideoOrientation’ is not a subtype of ‘UIInterfaceOrientation’
在阅读了关于降级方法之后,这很有意义,但我很难找到如何实现这种方法。
我是否需要编写一个辅助方法,它基本上通过UIInterfaceOrientation的所有可用值执行switch语句来使其工作?
答案 0 :(得分:26)
正如我在评论中提到的,由于AVCaptureVideoOrientation和UIInterfaceOrientation与他们的案例不匹配,您可以使用以下内容:
extension AVCaptureVideoOrientation {
var uiInterfaceOrientation: UIInterfaceOrientation {
get {
switch self {
case .LandscapeLeft: return .LandscapeLeft
case .LandscapeRight: return .LandscapeRight
case .Portrait: return .Portrait
case .PortraitUpsideDown: return .PortraitUpsideDown
}
}
}
init(ui:UIInterfaceOrientation) {
switch ui {
case .LandscapeRight: self = .LandscapeRight
case .LandscapeLeft: self = .LandscapeLeft
case .Portrait: self = .Portrait
case .PortraitUpsideDown: self = .PortraitUpsideDown
default: self = .Portrait
}
}
}
然后将其用作:
if let connection = cameraView.previewLayer?.connection {
connection.videoOrientation = AVCaptureVideoOrientation(ui:self.interfaceOrientation)
}
答案 1 :(得分:8)
谢谢,大卫。我更新到Swift 3并添加了UIDeviceOrientation:
extension AVCaptureVideoOrientation {
var uiInterfaceOrientation: UIInterfaceOrientation {
get {
switch self {
case .landscapeLeft: return .landscapeLeft
case .landscapeRight: return .landscapeRight
case .portrait: return .portrait
case .portraitUpsideDown: return .portraitUpsideDown
}
}
}
init(ui:UIInterfaceOrientation) {
switch ui {
case .landscapeRight: self = .landscapeRight
case .landscapeLeft: self = .landscapeLeft
case .portrait: self = .portrait
case .portraitUpsideDown: self = .portraitUpsideDown
default: self = .portrait
}
}
init?(orientation:UIDeviceOrientation) {
switch orientation {
case .landscapeRight: self = .landscapeLeft
case .landscapeLeft: self = .landscapeRight
case .portrait: self = .portrait
case .portraitUpsideDown: self = .portraitUpsideDown
default:
return nil
}
}
}
然后我将它与AVCapturePhotoOutput一起使用,如下所示:
if let connection = imageOutput.connection(withMediaType: AVMediaTypeVideo),
connection.isVideoOrientationSupported,
let orientation = AVCaptureVideoOrientation(orientation: UIDevice.current.orientation) {
connection.videoOrientation = orientation
}
它可能并不适用于所有情况,但由于我的界面不会随方向而改变,因此我会跳过倾听方向更改。
一般来说,更改用户界面可能会更好,这样用户就可以了解他们使用的方向。
答案 2 :(得分:5)
extension UIDeviceOrientation {
var videoOrientation: AVCaptureVideoOrientation? {
// Unlike UIInterfaceOrientation, the UIDeviceOrientation has reversed landscape left/right. Doh!
switch self {
case .portraitUpsideDown: return .portraitUpsideDown
case .landscapeRight: return .landscapeLeft
case .landscapeLeft: return .landscapeRight
case .portrait: return .portrait
default: return nil
}
}
}
extension UIInterfaceOrientation {
var videoOrientation: AVCaptureVideoOrientation? {
switch self {
case .portraitUpsideDown: return .portraitUpsideDown
case .landscapeRight: return .landscapeRight
case .landscapeLeft: return .landscapeLeft
case .portrait: return .portrait
default: return nil
}
}
}
答案 3 :(得分:0)
过早发布此约10分钟。
想通了,如果你偶然发现了这一点,那就像做
connection.videoOrientation = AVCaptureVideoOrientation.fromRaw(self.interfaceOrientation.toRaw())!
似乎有效。