My code is not working and its causing a runtime error. When the takePHoto func is called I dont know how to fix this.
import UIKit;import AVFoundation
class ViewController: UIViewController {
var b1 = UIButton()
var caputreSession = AVCaptureSession()
var backCamera : AVCaptureDevice?
var frontCamera : AVCaptureDevice?
var currentCamera: AVCaptureDevice?
var photoOutput : AVCapturePhotoOutput?
var image : UIImage?
var captureSESSION = AVCaptureSession()
var cameraPreviewLayer : AVCaptureVideoPreviewLayer?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setupCaputerSession()
setUpDevice()
setupInput()
setUpPreivewLayer()
startRunningCaptiureSessions()
[b1].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
b1.backgroundColor = .orange
b1.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
b1.addTarget(self, action: #selector(takePHoto), for: .touchDown)
cameraPreviewLayer?.frame = CGRect(x: 100, y: 300, width: 200, height: 200)
}
func setupCaputerSession (){
captureSESSION.sessionPreset = AVCaptureSession.Preset.photo
}
func setUpDevice(){
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes:[AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
let devices = deviceDiscoverySession.devices
for device in devices {
if device.position == AVCaptureDevice.Position.back {
backCamera = device
}
else if device.position == AVCaptureDevice.Position.front {
frontCamera = device
}
}
currentCamera = backCamera
}
func setupInput(){
do {
let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!)
caputreSession.addInput(captureDeviceInput)
photoOutput = AVCapturePhotoOutput()
photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey : AVVideoCodecType.jpeg])], completionHandler: nil)
captureSESSION.addOutput(photoOutput!)
}
catch{
print(error)
}
}
func setUpPreivewLayer(){
cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: caputreSession)
cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
cameraPreviewLayer?.frame = self.view.frame
self.view.layer.insertSublayer(cameraPreviewLayer!, at: 0)
}
func startRunningCaptiureSessions(){
caputreSession.startRunning()
}
@objc func takePHoto(){
let settings = AVCapturePhotoSettings()
photoOutput?.capturePhoto(with: settings, delegate: self)
let vc = previewVC()
vc.modalPresentationStyle = .overCurrentContext // actually .fullScreen would be better
self.present(vc, animated: true)
vc.image = self.image
}
}
extension ViewController : AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
if let imageData = photo.fileDataRepresentation(){
image = UIImage(data: imageData)
}
}
}
class previewVC: UIViewController {
var displayPic = UIImageView()
var image : UIImage!
var backBtn = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
[displayPic,backBtn].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
displayPic.backgroundColor = .red
backBtn.backgroundColor = .systemTeal
displayPic.frame = CGRect(x: 100, y: 200, width: 100, height: 100)
backBtn.frame = CGRect(x: 0, y: 100, width: 10, height: 10)
backBtn.addTarget(self, action: #selector(returnBack), for: .touchDown)
}
@objc func returnBack(){
let vc = previewVC()
vc.modalPresentationStyle = .overCurrentContext // actually .fullScreen would be better
self.present(vc, animated: true)
}
}