ViewfinderViewController

ViewfinderViewController

本文介绍了在轮换时自动调整AVCaptureVideoPreviewLayer大小的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个静态框架,其中我有一个名为ViewfinderViewController的类,它使用AVCaptureSession设置摄像机。此ViewController还将AVCaptureVideoPreviewLayer添加为其自己视图层的子图层:

I've programmed a static framework, and therein I have a class called ViewfinderViewController, that set's up the camera with an AVCaptureSession. This ViewController also add's an AVCaptureVideoPreviewLayer as sublayer to its own view's layer:

    // code in ViewfinderViewController.m
    previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession];
    previewLayer.frame = self.view.bounds;
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    [self.view.layer addSublayer:previewLayer];

ViewfinderViewController也进行一些视频处理,并提供框架用户注册一些委托方法,如果在某个已处理的框架中找到了感兴趣的内容或没有找到感兴趣的东西。

The ViewfinderViewController also does some video processing, and offers user's of the framework to register for some delegate methods, in case something of interest was found or was not found in one of the processed frames.

在我的实际应用程序的viewDidLoad方法中,我创建了一个ViewfinderViewController的实例,设置它的框架并将其视图添加为子视图:

In the viewDidLoad method of my real application, I create an instance of ViewfinderViewController, set it's frame and add it's view as a subview:

    // code in the app's view controller viewDidLoad method
    ViewfinderViewController *vfVC = [[ViewfinderViewController alloc] init];
    vfVC.view.frame = self.view.bounds;
    [self.view addSubview:vfVC.view];

这个工作正常,只要我忽略轮换(我直到现在才这样做)。我的主要问题是,ViewfinderViewController.view调整了它的框架大小,但AVCaptureVideoPreviewLayer没有。我有点困惑:预览层也不应该自动调整大小,因为对应于它的superLayer的视图是否正确调整大小?

This works fine, as long as I disregard rotation (which I did until now). My main problem is, that ViewfinderViewController.view resizes its frame, but the AVCaptureVideoPreviewLayer does not. I'm a bit puzzeled: Shouldn't the previewLayer also resize automatically, as the view corresponding to it's superLayer is resized correctly?

任何想法?我很乐意提供更多信息,但为了缩短问题,我现在不再进一步了解。谢谢。

Any ideas? I'll gladly provide more information, but to keep the question shorter I won't go any further for now. Thanks.

推荐答案

最后,我发现以下内容最适合我的应用。
在我的应用程序中,我现在将ViewFinderViewController添加为子视图控制器:

Finally, I've found the following to be working best for my app.In my application, I add the ViewFinderViewController now as child view controller:

- (void)viewWillAppear:(BOOL)animated;
{
    if ([self.childViewControllers containsObject:self.viewfinderViewController] == NO) {
        [self addChildViewController:self.viewfinderViewController];
        self.viewfinderViewController.view.frame = self.view.bounds;
        [self.view addSubview:self.viewfinderViewController.view];
        [self.viewfinderViewController didMoveToParentViewController:self];
    }
}

这样,willAnimateRotationToInterfaceOrientation:方法将自动调用,我之前从视图控制器转发,它将取景器的视图添加为子视图。

This way, the willAnimateRotationToInterfaceOrientation: method will be called automatically, which I previously forwarded from the view controller that added the viewfinder's view as it's subview.

此外,我在ViewfinderViewController的这个方法中更新previewLayer大小:

Furthermore, I update the previewLayer size in this method of ViewfinderViewController:

- (void)viewWillLayoutSubviews;
{
    self.previewLayer.frame = self.view.bounds;
}

我通过实现这两种方法来处理previewLayer的旋转:

I handle rotation of the previewLayer by implementing these two methods:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [CATransaction begin];
    [CATransaction setAnimationDuration:duration];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [self updatePreviewLayerForOrientation:toInterfaceOrientation];
    [CATransaction commit];
}

- (void)updatePreviewLayerForOrientation:(UIInterfaceOrientation)interfaceOrientation;
{
    // correct position of previewLayer
    CGSize newSize = self.view.bounds.size;
    self.previewLayer.position = CGPointMake(0.5 * newSize.width, 0.5 * newSize.height);

    // rotate the previewLayer, in order to have camera picture right
    switch (interfaceOrientation) {
        case UIInterfaceOrientationPortrait:
            [self.previewLayer setAffineTransform:CGAffineTransformMakeRotation(0)];
            break;

        case UIInterfaceOrientationLandscapeLeft:
            [self.previewLayer setAffineTransform:CGAffineTransformMakeRotation(M_PI/2)];
            break;

        case UIInterfaceOrientationLandscapeRight:
            [self.previewLayer setAffineTransform:CGAffineTransformMakeRotation(-M_PI/2)];
            break;

        case UIDeviceOrientationPortraitUpsideDown:
            [self.previewLayer setAffineTransform:CGAffineTransformMakeRotation(M_PI)];
            break;

        default:
            break;
    }
}

我希望这可以帮助所有将AVCaptureVideoPreviewLayer添加为sublayer,在界面旋转方面有调整大小和方向的问题。

I hope this helps everybody who is adding AVCaptureVideoPreviewLayer as a sublayer and has problems with resizing and orientation when it comes to interface rotation.

这篇关于在轮换时自动调整AVCaptureVideoPreviewLayer大小的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 00:31