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:
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.
You don't have to override the layoutSubivews or viewDidLayoutSUbviews method.
previewView
is constrainted to superview
(If you are using autolayout)previewLayer
is same as previewView
bounds
. Don't get confused while giving the frame value to bounds or bound value to frame.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
.
setupSession()
either in viewDidAppear
/viewWillAppear