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

19
我不知道这个问题是关于自动布局还是我做错了什么。
我有一个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()

你成功了吗? - Erik
不行。当我将代码移动到viewdidlayoutsubviews时,它根本不起作用。在视图上,我有uiview和tableciew。似乎自动布局以某种方式增加了uiview的高度,这就是为什么相机与uiview大小不同的原因。我不知道该如何处理它。 - 1110
请提供更多的代码以帮助诊断此问题。 - Erik
你尝试过使用 CGRectMake(0, 0, ParentView.width,ParentView.hight); 来设置 cameraView 的框架吗? - Ajay Gabani
@1110我现在也遇到了同样的问题,你是如何解决的?谢谢! - kaseOga
5个回答

18

在你的子视图布局完成后,你需要进行设置。在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 设置框架时,它将采用正确的方向。但要注意,你还需要根据旋转和其他操作来调整预览,并修改我使用的代码。抱歉这不是 Swift,但那并不重要。只需将实例化和设置移动到 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()

0

priviewLayer的约束设置为下面的代码,以便它占据整个屏幕。

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

希望这能对你有所帮助。

0

这对我在Swift 4.2中起作用了

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

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

-1
如果您想让图层完全填充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()

-2
如果您正在使用自动布局,则只需执行以下操作:
  1. 将相机视图的x设置为0,并将其宽度设置为屏幕大小
  2. 将前导和后续约束应用于superView
希望这可以帮助您。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接