Problems with auto-resizing AVCaptureVideoPreviewLayer while rotating

I programmed a static framework, and there I have a class called ViewfinderViewController that configured the camera using AVCaptureSession. This ViewController also adds AVCaptureVideoPreviewLayer as a sublayer to its own view layer:

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

ViewfinderViewController also performs some video processing and offers the framework user to register for some delegate methods if something interesting was found or was not found in one of the processed frames.

In the viewDidLoad method of my real application, I create an instance of ViewfinderViewController, set its frame and add it as a preview:

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

This works great as long as I don't pay attention to rotation (which I have done so far). My main problem is that ViewfinderViewController.view resizes its frame, but AVCaptureVideoPreviewLayer does not. I'm a little puzzled: shouldn't the preview automatically resize, since the corresponding superLayer view changes correctly?

Any ideas? I gladly provided more information, but to keep the question short, I will no longer go any further. Thanks.

+4
source share
1 answer

Finally, I found the following to work best for my application. In my application, I now add the ViewFinderViewController as a 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]; } } 

Thus, the willAnimateRotationToInterfaceOrientation: method will be called automatically, which I previously redirected from the view controller, which added the viewfinder view when it is being watched.

In addition, I update the preview size in this ViewfinderViewController method:

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

I handle the previewLayer rotation 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; } } 

Hope this helps everyone who adds AVCaptureVideoPreviewLayer as a sublevel and has problems with resizing and orientation when it comes to rotating the interface.

+9
source

Source: https://habr.com/ru/post/1436822/


All Articles