我使用AVFoundation框架来访问相机。在标准相机应用程序中,当方向更改时,仅更改按钮上图标的旋转。但是当我尝试做类似的事情时,我遇到了与方向更改动画相关的问题。预览视图旋转,其后面的区域为黑色,并且在转动时有图像抖动。
现在我有这个代码:
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:duration]
forKey:kCATransactionAnimationDuration];
if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft){
captureManager.previewLayer.transform=CATransform3DMakeRotation(M_PI/2, 0, 0, 1.0);
captureManager.previewLayer.frame = CGRectMake(0, 0, 480, 320);
} else if (toInterfaceOrientation==UIInterfaceOrientationPortrait){
captureManager.previewLayer.transform=CATransform3DMakeRotation(0, 0, 0, 1.0);
captureManager.previewLayer.frame = CGRectMake(0, 0, 320, 480);
} else if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight){
captureManager.previewLayer.transform=CATransform3DMakeRotation(M_PI+M_PI/2, 0, 0, 1.0);
captureManager.previewLayer.frame = CGRectMake(0, 0, 480, 320);
}
[CATransaction commit];
}
我的想法是使用变换动画来处理旋转动画,但我遇到了滑行的问题。
如何创建相机预览视图并解决方向更改问题?可能我必须使用其他仪器才能使用相机?不是AVFoundation框架?
我知道我可以锁定方向并使用加速度计来处理按钮图标。但是我遇到了一些子视图控制器的问题。
对不起,英语不好。
您需要禁用控制器的横向,并通过处理方向更改通知来更新图标等的布局。在本主题中,它被描述正确 - 如何处理AVCaptureVideoPreviewLayer中的自动旋转?
Nikita 的答案有效,但需要额外的代码来处理设备旋转时 UI 元素的行为。如果这太麻烦了,另一个选项(我实现并工作)是有 2 个不同的 UIWindow 实例,一个用于相机的预览层,另一个用于要显示的 UI 元素。请注意,要使其正常工作,包含 UI 元素的窗口需要具有透明背景。
我通过以下方式处理预览旋转更改。
P.S 所有子视图在故事板上都设置了相应的约束,所以我只更新视频预览层的帧。
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
DispatchQueue.main.async {
self.videoPreviewLayer.frame = self.previewView.bounds
self.setRotation()
}
}
func setRotation() {
let deviceOrientation = UIDevice.current.orientation
switch deviceOrientation {
case .landscapeLeft:
videoPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.landscapeRight
break
case .landscapeRight:
videoPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.landscapeLeft
break
case .portrait:
videoPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
break
case .portraitUpsideDown:
videoPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portraitUpsideDown
break
default:
break
}
}