Erik Erik - 6 months ago 47
iOS Question

AVCaptureVideoPreviewLayer looks to be iPhone 4 size

I'm using this code to display a camera in my iOS 9, Swift app:

Properties:

@IBOutlet weak var previewView: UIView!

var session: AVCaptureSession!
var input: AVCaptureDeviceInput!
var output: AVCaptureStillImageOutput!
var previewLayer: AVCaptureVideoPreviewLayer?


Delegate methods:

override func viewDidLoad() {
super.viewDidLoad()
}

override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
setupSession()
}

override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// Experimental / debugging
view.layoutSubviews()
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Experimental / debugging
previewLayer!.frame = previewView.bounds
}


Camera methods:

func setupSession() {
session = AVCaptureSession()
session.sessionPreset = AVCaptureSessionPresetPhoto

let camera = frontCamera()

do { input = try AVCaptureDeviceInput(device: camera) } catch { return }

output = AVCaptureStillImageOutput()
output.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]

guard session.canAddInput(input) && session.canAddOutput(output) else { return }

session.addInput(input)
session.addOutput(output)

previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer!.videoGravity = AVLayerVideoGravityResizeAspect
previewLayer!.frame = previewView.bounds
previewLayer!.connection?.videoOrientation = .Portrait

previewView.layer.addSublayer(previewLayer!)

session.startRunning()
}

func frontCamera() -> AVCaptureDevice! {
let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
for device in devices {
if (device.position == AVCaptureDevicePosition.Front) {
return device as! AVCaptureDevice
}
}
return nil
}


However, the camera is displayed like this:

enter image description here

And it appears to be equivalent to the display size of an iPhone 4.

How can I solve this? I've tried setting the frame in
viewDidLayoutSubviews
, but I can't get it sized properly.

Answer

You don't have to override the layoutSubivews or viewDidLayoutSUbviews method.

  1. Make sure the previewView is constrainted to superview (If you are using autolayout)
  2. Make sure the bounds of previewLayer is same as previewView bounds. Don't get confused while giving the frame value to bounds or bound value to frame.
  3. set the video gravity of the preview layer to AVLayerVideoGravityResizeAspectFill.

4.You can position the previewLayer and make it center to the previewView . Use position property of previewLayer and set it to the center of previewView.

  1. call the setupSession() either in viewDidAppear/viewWillAppear