如何设置相机视图以填充其父视图

Posted

技术标签:

【中文标题】如何设置相机视图以填充其父视图【英文标题】:How to set camera view to fill it's parent view 【发布时间】:2015-04-09 09:31:23 【问题描述】:

我不知道这个问题是与自动布局有关还是我做错了什么。 我有一个UIViewController 和一个UIView 在里面。 我正在使用AVCaptureSession 将相机视图放入其中。 问题是当我在视图内部加载相机视图时,它不会填充该视图,因此我在左侧和右侧有间隙。 我想做的是用相机填充整个UIView。 这是我的代码:

...
@IBOutlet weak var camView: UIView!
var previewLayer    : AVCaptureVideoPreviewLayer!

override func viewDidLoad() 
...
previewLayer = AVCaptureVideoPreviewLayer.layerWithSession(session) as! AVCaptureVideoPreviewLayer
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
previewLayer.frame = self.camView.layer.bounds
self.camView.layer.addSublayer(previewLayer)
session.startRunning()

【问题讨论】:

它对你有用吗? 没有。当我将代码移动到 viewdidlayoutsubviews 时,它根本不起作用。在视图上,我有 uiview 和 tableciew 波纹管。它接缝自动布局以某种方式增加了uiview的高度,这就是为什么Camera的大小不像uiview。不知道怎么处理。 请提供更多代码来帮助诊断。 你试过 CGRectMake(0, 0, ParentView.width,ParentView.hight); ?设置cameraView的框架。 @1110 我现在也遇到了同样的问题,你是怎么解决的?谢谢! 【参考方案1】:

您需要在布局子视图后进行设置。在viewDidLayoutSubviews

-(void)viewDidLayoutSubviews

    [self setupAVCapture];



- (void)setupAVCapture 
    NSError *error = nil;

    AVCaptureSession *session = [AVCaptureSession new];
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
        [session setSessionPreset:AVCaptureSessionPreset640x480];
    else
        [session setSessionPreset:AVCaptureSessionPresetPhoto];

    // Select a video device, make an input
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];

    if ([session canAddInput:deviceInput])
        [session addInput:deviceInput];

    AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];
        [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

    previewLayer.frame = self.camView.bounds;
    [self.camView.layer addSublayer:previewLayer];
    [session startRunning];

可能发生在您的viewDidLoad 中的边界尚未准确设置,因为尚未根据其约束布置子视图。当您改为在viewDidLayoutSubviews 中为previewLayer 设置框架时,它将采用正确的方向。不过要小心,您还需要调整旋转预览,以及修改我使用的代码。抱歉,它不是很快,但这不重要。只需将您的实例化和设置移动到viewDidLayoutSubviews

所以对于你的代码,你应该这样做:

override func viewDidLayoutSubviews() 
...
previewLayer = AVCaptureVideoPreviewLayer.layerWithSession(session) as! AVCaptureVideoPreviewLayer
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
previewLayer.frame = self.camView.layer.bounds
self.camView.layer.addSublayer(previewLayer)
session.startRunning()

【讨论】:

【参考方案2】:

priviewLayer 约束设置为如下代码,使其占据整个屏幕。

Leading Space = 0 from mainView
Top Space = 0 from mainView
Bottom Space = 0 from mainView 
Trailing Space = 0 from mainView

希望对您有所帮助。

【讨论】:

【参考方案3】:

这在 Swift 4.2 中对我有用

只需在 viewDidLayoutSubviews() 函数中将 AVCaptureVideoPreviewLayer 的实例框架设置为父视图的框架,如下所示:

override func viewDidLayoutSubviews()
        super.viewDidLayoutSubviews()
        avCaptureVideoPreviewLayerInstance.frame = self.parentView.bounds
    

【讨论】:

【参考方案4】:

如果您希望您的图层正确填充 UIView,您不妨为其定义约束:

self.camView.layer.addSublayer(previewLayer)
self.camView.layer.layoutManager = CAConstraintLayoutManager.layoutManager();
self.camView.layer.addConstraint(CAConstraint.constraintWithAttribute(CAConstraintAttribute.MinX, relativeTo: self.camView.layer, attribute: CAConstraintAttribute.MinX, scale: 1, offset: 0));
self.camView.layer.addConstraint(CAConstraint.constraintWithAttribute(CAConstraintAttribute.MaxX, relativeTo: self.camView.layer, attribute: CAConstraintAttribute.MaxX, scale: 1, offset: 0));
self.camView.layer.addConstraint(CAConstraint.constraintWithAttribute(CAConstraintAttribute.Width, relativeTo: self.camView.layer, attribute: CAConstraintAttribute.Width, scale: 1, offset: 0));
self.camView.layer.addConstraint(CAConstraint.constraintWithAttribute(CAConstraintAttribute.Height, relativeTo: self.camView.layer, attribute: CAConstraintAttribute.Height, scale: 1, offset: 0));
session.startRunning()

【讨论】:

【参考方案5】:

如果您使用的是自动布局,那么只需执行以下操作:

    设置您的相机视图 x=0 和屏幕尺寸 对 superView 应用前导和尾随约束

希望这会对你有所帮助。

【讨论】:

以上是关于如何设置相机视图以填充其父视图的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式为其父视图添加视图大小?

如何在我的 Android 应用程序中使视图填充其父级的整个宽度?

如何在滚动视图中填充图像以填充屏幕?

如何使 UIBezierPath 从中心填充

Xcode 6 Interface Builder 视图大小错误

相机 API - 图像太小