Я хочу реализовать действия камеры, такие как сделать снимок (и передать его следующему контроллеру), включить / выключить вспышку, сменить камеру (заднюю / переднюю), но я никогда не делал этого раньше. Я реализовал полнофункциональный контроллер камеры со всем интерфейсом, созданным программно.
Как я могу сделать эти действия? Я нашел некоторые ответы здесь, но это работает только для Swift 2, я использую 4-ую версию.
My CameraViewController
import UIKit
import AVFoundation
class CameraViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var captureSession = AVCaptureSession()
var backCamera: AVCaptureDevice?
var frontCamera: AVCaptureDevice?
var currentCamera: AVCaptureDevice?
var photoOutput: AVCapturePhotoOutput?
var cameraPreviewLayer: AVCaptureVideoPreviewLayer?
var image: UIImage?
var style:UIStatusBarStyle = .default
var imagePicker: UIImagePickerController!
lazy var UI = CameraUI(view: self.view)
override func viewDidLoad() {
super.viewDidLoad()
addUIElements()
setupCaptureSession()
setupDevice()
setupInputOutput()
setupPreviewLayer()
startRunningCaptureSession()
addActions()
}
func addActions(){
UI.changeCamera.addTarget(self, action: #selector(actionChange), for: .touchUpInside)
UI.changeFlash.addTarget(self, action: #selector(actionFlash), for: .touchUpInside)
UI.makePhoto.addTarget(self, action: #selector(actionPhoto), for: .touchUpInside)
}
@objc func actionChange(){
let settings = AVCapturePhotoSettings()
photoOutput?.capturePhoto(with: settings, delegate: self)
}
@objc func actionFlash(){
let settings = AVCapturePhotoSettings()
photoOutput?.capturePhoto(with: settings, delegate: self)
}
@objc func actionPhoto(){
let settings = AVCapturePhotoSettings()
photoOutput?.capturePhoto(with: settings, delegate: self)
let addPhotoVC = AddPhotoFromCameraViewController()
self.navigationController?.pushViewController(addPhotoVC, animated: true)
}
private func addUIElements(){
UI.addElementsToSuperView()
view.layoutIfNeeded()
}
func setupCaptureSession(){
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 setupInputOutput(){
do{
let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!)
captureSession.addInput(captureDeviceInput)
photoOutput = AVCapturePhotoOutput()
photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
captureSession.addOutput(photoOutput!)
}catch{
print(error)
}
}
func setupPreviewLayer(){
cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
cameraPreviewLayer?.frame = self.view.frame
view.layer.insertSublayer(cameraPreviewLayer!, at: 0)
}
func startRunningCaptureSession(){
captureSession.startRunning()
}
override func viewWillAppear(_ animated: Bool) {
setupNavBar()
navigationController?.navigationBar.prefersLargeTitles = false
navigationController?.navigationItem.largeTitleDisplayMode = .automatic
hidenTabBar()
}
override func viewWillDisappear(_ animated: Bool) {
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationItem.largeTitleDisplayMode = .always
shownTabBar()
}
func setupNavBar(){
title = "Camera"
navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: PineappleColors.green.color]
guard let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else { return }
statusBar.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.65)
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = true
navigationController?.navigationBar.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.65)
navigationController?.view.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.65)
navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
navigationController?.navigationBar.tintColor = PineappleColors.green.color
self.style = .lightContent
self.setNeedsStatusBarAppearanceUpdate()
}
}
Расширения
extension CameraViewController: AVCapturePhotoCaptureDelegate{
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
if let imageData = photo.fileDataRepresentation() {
print(imageData)
image = UIImage(data: imageData)
//perform segue
}
}
}