如何更改某些功能以使其与iOS 10或更低版本兼容,以实现我的snapchat中的某些功能(例如相机视图控制器) [英] How to change some function to be compatible for iOS 10 or below for some function in my snapchat like camera view controller

查看:226
本文介绍了如何更改某些功能以使其与iOS 10或更低版本兼容,以实现我的snapchat中的某些功能(例如相机视图控制器)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个视图控制器,以制作像Snapchat相机这样的相机视图控制器。我的以下代码非常适合iOS 11或更高版本。老实说,我并没有真正掌握我的代码,因为我只是按照本教程的指导来学习像摄像头视图控制器之类的东西

I am making a view controller to make a camera view controller like snapchat camera. my code below is worked perfectly for iOS 11 or above. to be honest, I don't really grasp my code since i just follow along the tutorial for this snapchat like camera view controller

import UIKit
import AVFoundation
import SVProgressHUD
class CameraVC: UIViewController {

    @IBOutlet weak var timeLabel: UILabel!
    @IBOutlet weak var dateLabel: UILabel!
    @IBOutlet weak var cameraButton: DesignableButton!
    @IBOutlet weak var retryButton: DesignableButton!

    // to receive data from MainMenuVC
    var employeeData : Employee?
    var checkinData = CheckIn()

    var captureSession = AVCaptureSession()

    // which camera input do we want to use
    var backCamera: AVCaptureDevice?
    var frontCamera: AVCaptureDevice?

    // to keep track which camera do we use currently
    var currentDevice: AVCaptureDevice?

    var photoOutput: AVCapturePhotoOutput?
    var cameraPreviewLayer: AVCaptureVideoPreviewLayer?

    var toggleCameraGestureRecognizer = UISwipeGestureRecognizer()
    var zoomInGestureRecognizer = UISwipeGestureRecognizer()
    var zoomOutGestureRecognizer = UISwipeGestureRecognizer()

    var thereIsAnError : Bool = false {
        didSet {
            if thereIsAnError {
                cameraButton.isHidden = true
                cameraButton.isEnabled = false
                retryButton.isHidden = false
                retryButton.isEnabled = true
            } else {
                cameraButton.isHidden = false
                cameraButton.isEnabled = true
                retryButton.isHidden = true
                retryButton.isEnabled = false
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        getDateTimeFromServer()

        // initial value
        thereIsAnError = false
        timeLabel.text = ""
        dateLabel.text = ""
        cameraButton.isEnabled = false
        cameraButton.alpha = 0.4

        setupCaptureSession()
        setupDevice()
        setupInputOutput()
        setupPreviewLayer()
        startRunningCaptureSession()
        setGestureRecognizer()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if checkinData.dateTime != nil {
            SVProgressHUD.dismiss()
        }
    }

    @IBAction func shutterButtonDidPressed(_ sender: Any) {
        // when the button is pressed, we capture the image and set the photoOutput
        let settings = AVCapturePhotoSettings()
        photoOutput?.capturePhoto(with: settings, delegate: self)

        // perform segue is below in the AVCapturePhotoCaptureDelegate
    }

    @IBAction func retryButtonDidPressed(_ sender: Any) {
        if checkinData.dateTime == nil {
            getDateTimeFromServer()
        }
    }
}

extension CameraVC {

    // MARK: - Helper Methods

    // MARK: - Helper Methods
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToCheckinDetail" {
            let checkinDetailTVC = segue.destination as! CheckinDetailVC
            checkinDetailTVC.dataOfCheckin = checkinData
            checkinDetailTVC.dataOfEmployee = employeeData

            // to set the navbar back button title in the checkinDetailVC
            navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)

        }
    }

    func  getDateTimeFromServer() {

        SVProgressHUD.show(withStatus: "Loading Data")

        NetworkingService.getCurrentTimeFromServer { (result) in
            switch result {
            case .failure:
                self.thereIsAnError = true
                SVProgressHUD.dismiss()
                self.showAlert(alertTitle: "Sorry", alertMessage: "Internet connection issue, please tap the retry button.", actionTitle: "Back")
            case .success(let timeFromServer) :
                guard let stringDateTimeServer = timeFromServer as? String else {return}
                self.checkinData.dateTime = stringDateTimeServer

                let dateTimeService = DateTimeService(fromDateTimeString: stringDateTimeServer)
                let time = dateTimeService.parsingDateAndTime()?.timeOnly
                self.timeLabel.text = "\(time ?? "-")"
                self.dateLabel.text = DateTimeService.changeFormat(of: stringDateTimeServer, toFormat: "dd MMM yyyy")


                self.cameraButton.isEnabled = true
                self.cameraButton.alpha = 1
                self.thereIsAnError = false

                SVProgressHUD.dismiss()
            }
        }
    }

    func setGestureRecognizer() {
        // change camera from front to back
        toggleCameraGestureRecognizer.direction = .up
        toggleCameraGestureRecognizer.addTarget(self, action: #selector(self.switchCamera))
        view.addGestureRecognizer(toggleCameraGestureRecognizer)

        // Zoom In recognizer
        zoomInGestureRecognizer.direction = .right
        zoomInGestureRecognizer.addTarget(self, action: #selector(zoomIn))
        view.addGestureRecognizer(zoomInGestureRecognizer)

        // Zoom Out recognizer
        zoomOutGestureRecognizer.direction = .left
        zoomOutGestureRecognizer.addTarget(self, action: #selector(zoomOut))
        view.addGestureRecognizer(zoomOutGestureRecognizer)
    }

    func setupCaptureSession() {
        // to specify image resolution and quality we want, we set to the highest resolution possible
        captureSession.sessionPreset = AVCaptureSession.Preset.photo
    }

    func setupDevice() {
        // to decide whether we use front or back camer

        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
            }
        }
        // default device
        currentDevice = frontCamera
    }

    func setupInputOutput() {
        //  after the camera capture that image (input), we generate the image DATA (output)
        // put the input and output to capture Session

        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!)
            captureSession.addInput(captureDeviceInput)
            photoOutput = AVCapturePhotoOutput()
            photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
            captureSession.addOutput(photoOutput!)
        } catch {
            print(error)
        }
    }

    func setupPreviewLayer() {
        // to display image data on the screen

        cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
        cameraPreviewLayer?.frame = self.view.frame
        self.view.layer.insertSublayer(cameraPreviewLayer!, at: 0)
    }

    @objc func switchCamera() {
        captureSession.beginConfiguration()

        // Change the device based on the current camera
        let newDevice = (currentDevice?.position == AVCaptureDevice.Position.back) ? frontCamera : backCamera

        // Remove all inputs from the session
        for input in captureSession.inputs {
            captureSession.removeInput(input as! AVCaptureDeviceInput)
        }

        // Change to the new input
        let cameraInput:AVCaptureDeviceInput
        do {
            cameraInput = try AVCaptureDeviceInput(device: newDevice!)
        } catch {
            print(error)
            return
        }

        if captureSession.canAddInput(cameraInput) {
            captureSession.addInput(cameraInput)
        }

        currentDevice = newDevice
        captureSession.commitConfiguration()
    }

    @objc func zoomIn() {
        if let zoomFactor = currentDevice?.videoZoomFactor {
            if zoomFactor < 5.0 {
                let newZoomFactor = min(zoomFactor + 1.0, 5.0)
                do {
                    try currentDevice?.lockForConfiguration()
                    currentDevice?.ramp(toVideoZoomFactor: newZoomFactor, withRate: 1.0)
                    currentDevice?.unlockForConfiguration()
                } catch {
                    print(error)
                }
            }
        }
    }

    @objc func zoomOut() {
        if let zoomFactor = currentDevice?.videoZoomFactor {
            if zoomFactor > 1.0 {
                let newZoomFactor = max(zoomFactor - 1.0, 1.0)
                do {
                    try currentDevice?.lockForConfiguration()
                    currentDevice?.ramp(toVideoZoomFactor: newZoomFactor, withRate: 1.0)
                    currentDevice?.unlockForConfiguration()
                } catch {
                    print(error)
                }
            }
        }
    }

    func startRunningCaptureSession() {
        // to start capturing the data
        captureSession.startRunning()
    }
}

extension CameraVC: AVCapturePhotoCaptureDelegate {
    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        if let imageData = photo.fileDataRepresentation() {
            checkinData.photo = UIImage(data: imageData)
            performSegue(withIdentifier: "goToCheckinDetail", sender: nil)
        }
    }
}

我将部署目标设置为iOS 10.3,但出现错误,提示某些方法仅适用于iOS 11或更高版本。

but when I set my deployment target to iOS 10.3, I got an error that said some method is only available for iOS 11 or newer.

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        if let imageData = photo.fileDataRepresentation() {
            checkinData.photo = UIImage(data: imageData)
            performSegue(withIdentifier: "goToCheckinDetail", sender: nil)
        }
    }





  1. AVCapturePhoto'仅在iOS上可用11.0或更高版本

  2. fileDataRepresentation()'仅适用于iOS 11.0或更高版本


func setupInputOutput() {
        //  after the camera capture that image (input), we generate the image DATA (output)
        // put the input and output to capture Session

        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!)
            captureSession.addInput(captureDeviceInput)
            photoOutput = AVCapturePhotoOutput()
            photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
            captureSession.addOutput(photoOutput!)
        } catch {
            print(error)
        }
    }




'jpeg'是仅可用在iOS 11.0或更高版本上不可用

'jpeg' is only available on iOS 11.0 or newer

请帮助我,我需要某些功能(至少与iOS 10相同)或

Please help me, I need some function that equal to those function for iOS 10 (at least) or below.

推荐答案


  1. 创建一个AVCapturePhotoOutput对象。使用其属性来确定支持的捕获设置并启用某些功能(例如,是否捕获实时照片)。

  1. Create an AVCapturePhotoOutput object. Use its properties to determine supported capture settings and to enable certain features (for example, whether to capture Live Photos).

fileprivate var photoOutput: AVCapturePhotoOutput!


  • 创建并配置AVCapturePhotoSettings对象以为特定对象选择
    功能和设置捕获(例如,是否启用图像稳定或闪光)。

  • Create and configure an AVCapturePhotoSettings object to choose features and settings for a specific capture (for example, whether to enable image stabilization or flash).

    photoOutput = AVCapturePhotoOutput()
    if self.session.canAddOutput(photoOutput) {
         self.session.addOutput(photoOutput)
    }
    


  • 通过将照片设置对象传递到
    capturePhoto(with:delegate:)方法以及实现AVCapturePhotoCaptureDelegate的委托对象来捕获图像协议。照片捕获输出然后调用您的代表,以在捕获过程中通知您重大事件。

  • Capture an image by passing your photo settings object to the capturePhoto(with:delegate:) method along with a delegate object implementing the AVCapturePhotoCaptureDelegate protocol. The photo capture output then calls your delegate to notify you of significant events during the capture process.

    queue.async { self.photoOutput.capturePhoto(with: AVCapturePhotoSettings(), delegate: self) }
    


  • 这篇关于如何更改某些功能以使其与iOS 10或更低版本兼容,以实现我的snapchat中的某些功能(例如相机视图控制器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆