Swift 4 реализует действия для контроллера камеры - PullRequest
0 голосов
/ 10 января 2019

Я хочу реализовать действия камеры, такие как сделать снимок (и передать его следующему контроллеру), включить / выключить вспышку, сменить камеру (заднюю / переднюю), но я никогда не делал этого раньше. Я реализовал полнофункциональный контроллер камеры со всем интерфейсом, созданным программно. Как я могу сделать эти действия? Я нашел некоторые ответы здесь, но это работает только для Swift 2, я использую 4-ую версию.

screenshot

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
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...