自动调整AVCaptureVideoPreviewLayer旋转时的问题

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

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

ViewfinderViewController也做一些video处理,并提供框架的用户注册一些委托方法,以防万一感兴趣的事情被发现或在其中一个处理的框架中找不到。

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

  // 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不。 我有点puzzeled:不应该previewLayer也自动resize,因为它的superLayer对应的视图被正确resize?

有任何想法吗? 我很乐意提供更多的信息,但为了保持这个问题,我现在不会再进一步​​了。 谢谢。

最后,我发现以下是我的应用程序最好的工作。 在我的应用程序中,我现在添加ViewFinderViewController作为子视图控制器:

 - (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:方法将被自动调用,我之前从视图控制器转发,该视图控制器将取景器的视图添加为子视图。

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

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

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

 - (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作为子图层的人,并且在界面旋转时遇到resize和方向的问题。