Как установить вид камеры, чтобы заполнить его родительским представлением

Я не знаю, связана ли эта проблема с автомаркетингом или я что-то делаю неправильно.
У меня есть 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()

Ответы

Ответ 1

Вам необходимо провести настройку после того, как ваши подпрограммы будут выложены. В viewDidLayoutSubviews

Add view

Add outlet

Add Constraints

-(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, так как подсмотры еще не были изложены в соответствии с их ограничениями. Когда вы установите рамку для previewLayer в viewDidLayoutSubviews, она примет правильную ориентацию. Будьте осторожны, вам также нужно будет настроить предварительный просмотр при повороте, а что нет и изменить код, который я использовал. Извините, что это не быстро, но это не имеет значения. Просто переместите свой экземпляр и настройки в 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

Если вы хотите, чтобы ваш слой правильно заполнил 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()

Ответ 3

Чтобы установить ограничения priviewLayer, как показано ниже, чтобы он занял весь экран.

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

Надеюсь, что это поможет вам.

Ответ 4

Если вы используете автозапуск, просто выполните:

  • Установите вид камеры x = 0 и размер экрана
  • Применить ведущее и конечное ограничение для супервизора

Надеюсь, это поможет вам.