如何在AVCaptureVideoPreviewLayer中处理自动旋转? [英] How to handle autorotation in AVCaptureVideoPreviewLayer?

查看:156
本文介绍了如何在AVCaptureVideoPreviewLayer中处理自动旋转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序支持除PortraitUpsideDown之外的所有方向。
在我的视图层次结构中,我有一个AVCaptureVideoPreviewLayer作为顶视图中的子图层,即UIImageView。然后在视图层次结构下面是几个显示控件的叠加视图。

My application supports all orientations except PortraitUpsideDown. In my view hierarchy I have an AVCaptureVideoPreviewLayer as a sublayer in the top view which is UIImageView. Then below it in view hierarchy are several overlay views showing controls.

叠加视图在方向更改时正常工作,但我不知道如何使用此AVCaptureVideoPreviewLayer。我希望它的行为类似于Camera应用程序,以便previewLayer保持静止并且控件可以平滑地重新组织。现在,由于主视图在方向更改时旋转,我的预览图层也会旋转,这意味着在横向视图中它保持纵向视图,仅占用屏幕的一部分,相机的图片也旋转90度。我已设法手动旋转预览图层,但之后它有这个方向更改动画,这导致在动画期间看到背景一段时间。

Overlay views are working properly with orientation changes, but I don't how to be with this AVCaptureVideoPreviewLayer. I want it to behave like in Camera app, so that previewLayer stays still and controls are smoothly reorganized. Right now since the main view is rotated on orientation change, my preview layer is also rotated, which means that in landscape view it stays in portrait view, taking only part of the screen and the picture from camera being also rotated by 90 degrees. I've managed to rotate the preview layer manually, but then it has this orientation change animation, which leads to the background being seen for a while during the animation.

那么在使previewLayer保持静止的同时自动旋转控件的正确方法是什么?

So what is the proper way to autorotate the controls while making previewLayer stay still?

推荐答案

在我的实现中,我为我的视图子类化了UIView,我想要旋转这个视图的viewController,它只是NSObject的子类。

In my implementation I have subclassed the UIView for my view which I want to rotate and something like viewController for this view which is just a subclass of NSObject.

在这个viewController中,我做了与方向变化相关的所有检查,决定是否应该改变目标视图的方向,如果是,那么我调用视图的方法来改变方向。

In this viewController I do all the the checks related to changes of orientation, make decision if I should change orientation of my target view, and if yes, then I call method of my view for changing its orientation.

首先,我们需要将整个应用程序界面的方向修复为纵向模式,以便我们的ACCaptureVideoPreviewLayer始终保持静止。
这是在 MainViewController.h中完成的

First of all we need to fix the orientation of whole application interface to Portrait mode, so that our ACCaptureVideoPreviewLayer always stays still. This is done in the MainViewController.h:

(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation`
{
    return interfaceOrientation==UIInterfaceOrientationPortrait;
}

除了肖像外,它向所有方向返回NO。

It returns NO to all orientations except Portrait.

为了让我们的自定义viewController能够跟踪设备方向的变化,我们需要让它成为相应通知的观察者:

In order to our custom viewController be able to track the changes of device orientation we need to make it an observer of corresponding notifications:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(orientationChanged) name:UIDeviceOrientationDidChangeNotification object:nil];

我将这些行放在(void)awakeFromNib viewController的方法。
因此每次更改设备方向时,都会调用viewController的方法 orientationChanged

I put these lines in the (void)awakeFromNib method of my viewController. So each time the device orientation is changed, the viewController's method orientationChanged will be called.

目的是检查设备的新方向是什么,设备的最后方向是什么,并决定是否更改它。以下是实现:

Its purpose is to check what is the new orientation of device, what was the last orientation of device and decide if to change it. Here is the implementation:

if(UIInterfaceOrientationPortraitUpsideDown==[UIDevice currentDevice].orientation ||
    lastOrientation==(UIInterfaceOrientation)[UIDevice currentDevice].orientation) 
    return;
    [[UIApplication sharedApplication]setStatusBarOrientation:[UIDevice currentDevice].orientation animated:NO];

    lastOrientation=[UIApplication sharedApplication].statusBarOrientation;
    [resultView orientationChanged];

如果方向与之前相同或在PortraitUpsideDown中,则不执行任何操作。
否则它会将状态栏方向设置为正确的方向,这样当有来电或骨化时,它将出现在屏幕的正确一侧。然后我在目标视图中调用also方法,其中完成了新方向的所有相应更改,例如旋转,调整大小,在此视图中移动与新方向对应的界面的其他元素。

If the orientation is the same as before or in PortraitUpsideDown then do nothing. Else it sets the status bar orientation to the proper one, so that when there is an incoming call or ossification, it will appear on the proper side of the screen. And then I call also method in the target view where all the corresponding changes for new orientation are done, like rotating, resizing, moving the other elements of interface in this view corresponding to the new orientation.

以下是目标视图中 orientationChanged 的实现:

Here is the implementation of the orientationChanged in target view:

Float32 angle=0.f;
UIInterfaceOrientation orientation=[UIApplication sharedApplication].statusBarOrientation;

switch (orientation) {
    case UIInterfaceOrientationLandscapeLeft: 
        angle=-90.f*M_PI/180.f;
        break;
    case UIInterfaceOrientationLandscapeRight: 
            angle=90.f*M_PI/180.f;
        break;
    default: angle=0.f;
        break;
}   
if(angle==0 && CGAffineTransformIsIdentity(self.transform)) return;

CGAffineTransform transform=CGAffineTransformMakeRotation(angle);

[UIView beginAnimations:@"rotateView" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.35f];

self.transform=transform;

[UIView commitAnimations];

当然,您可以添加任何其他更改,例如翻译,缩放您需要的界面的不同视图响应新的方向并为它们设置动画。

Of course here you can add any other changes like translation, scaling of different views of your interface that need to respond to new orientation and animate them.

此外,您可能不需要viewController,但只在视图的类中执行。
希望一般的想法是明确的。

Also you may not need the viewController for this, but do all just in the class of your view. Hope that the general idea is clear.

另外,当你不需要时,不要忘记停止获取方向更改的通知:

Also don't forget to stop getting notification for orientation changes when you don't need them like:

[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];

这篇关于如何在AVCaptureVideoPreviewLayer中处理自动旋转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆