@property (nonatomic,strong) IBOutlet UIView *previewView;
previewView将使用以下预览图层最终在我的iPhone上显示相机内容的预览.
@property (nonatomic,strong) AVCaptureVideoPreviewLayer *previewLayer;
我在故事板中的previewView上设置了约束,因此遇到了以下问题.
self.previewLayer.frame = self.previewView.bounds; // This doesn't work self.previewLayer.videoGravity = AVLayerVideoGravityResize; [self.previewView.layer addSublayer:self.previewLayer];
previewLayer被添加到previewView subLayer中,但它没有显示在正确的参数(宽度和高度)中.我认为这是由于在autolayout上使用约束.
我该如何解决这个问题?
更新:我也尝试了以下内容:
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspect; CALayer *rootLayer = [previewView layer]; rootLayer.frame = self.previewView.bounds; [rootLayer setMasksToBounds:YES]; [self.previewLayer setFrame:[rootLayer bounds]]; [rootLayer addSublayer:self.previewLayer];
它似乎显示如下:http://cl.ly/image/3T3o0O1E3U17
越来越近,但仍然非常关闭.
解决方法
问题是当你使用autolayout时,你设置了previewLayer之后你的UIViewController子视图的框架/边界会发生变化,而且预览层本身也不会相应更新!这是因为CALayers的布局完全由一个人自己的代码控制(另见相关答案:https://stackoverflow.com/a/27735617/623685).
要解决这个问题,您必须覆盖UIViewController的viewDidLayoutSubviews方法,以便每次子视图的布局更改时更新previewLayer的位置和边界(可能还有其他).
在下文中,我将描述我是如何详细解决它的:
我的情况实际上有点复杂,因为我使用的是OpenCV iOS框架2.4.9.这里,预览层由名为CvVideoCamera的OpenCV类创建和管理.因此我必须创建一个CvVideoCamera的子类,我添加了以下方法:
- (void)updatePreviewLayer { self.customPreviewLayer.bounds = CGRectMake(0,self.parentView.frame.size.width,self.parentView.frame.size.height); [self layoutPreviewLayer]; }
说明:parentView是您传递给CvVideoCamera的UIView,以指定预览图层的位置和大小. customPreviewLayer是由CvVideoCamera管理的预览图层. layoutPreviewLayer是一种基本上更新图层位置的方法:https://github.com/Itseez/opencv/blob/2.4/modules/highgui/src/cap_ios_video_camera.mm#L211
然后我简单地从我的UIViewController调用这个方法,如下所示:
- (void)viewDidLayoutSubviews { NSLog(@"viewDidLayoutSubviews"); [super viewDidLayoutSubviews]; [self.myCameraView updatePreviewLayer]; }