如何创建一个按钮来更改 Swift 中的相机视图?

How to create a button to change the camera view in Swift?

我想知道如何在按下按钮时更改相机视图。目前,我使用的是布尔值 var camera = false,当我按下按钮时,我想将值更改为 true 并获取另一个摄像头。但这是行不通的。 我现在有这个:

 @IBAction func changeCamera(sender: AnyObject) {

    camera = true

}

override func viewWillAppear(animated: Bool) {

    captureSession = AVCaptureSession()
    captureSession!.sessionPreset = AVCaptureSessionPresetPhoto
    var captureDevice:AVCaptureDevice! = nil
    //var backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    if (camera == false){
    let videoDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)


    for device in videoDevices{
        let device = device as AVCaptureDevice
        if device.position == AVCaptureDevicePosition.Front {
            captureDevice = device
            break
        }
    }
    } else {
        var captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

    }

    var error: NSError?
    var input = AVCaptureDeviceInput(device: captureDevice, error: &error)

    if error == nil && captureSession!.canAddInput(input) {
        captureSession!.addInput(input)

        stillImageOutput = AVCaptureStillImageOutput()
        stillImageOutput!.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
        if captureSession!.canAddOutput(stillImageOutput) {
            captureSession!.addOutput(stillImageOutput)

            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            previewLayer!.videoGravity = AVLayerVideoGravityResizeAspect
            previewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.Portrait
            previewView.layer.addSublayer(previewLayer)

            captureSession!.startRunning()
        }
    }

}

问题出在您设置相机源的地方。

您正在 viewDidAppear 中设置它,只有当视图出现在设备上时才会调用它。这是每当您从另一个视图控制器导航到该视图控制器或关闭此视图控制器正在呈现的呈现视图控制器时。

我的建议是将相机选择代码移动到它自己的函数中,该函数由 viewDidLoad 以及调用 changeCamera 操作时调用。

@IBAction func changeCamera(sender: AnObject?) {
    camera = !camera

    reloadCamera()
}


func viewDidAppear(animated: Bool) {
    // normal code

    reloadCamera()
}

func reloadCamera() {
    // camera loading code
    captureSession = AVCaptureSession()
    captureSession!.sessionPreset = AVCaptureSessionPresetPhoto
    var captureDevice:AVCaptureDevice! = nil
    // var backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    if (camera == false) {
        let videoDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)


        for device in videoDevices{
            let device = device as AVCaptureDevice
            if device.position == AVCaptureDevicePosition.Front {
                captureDevice = device
                break
            }
        }
    } else {
        var captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    }

    var error: NSError?
    var input = AVCaptureDeviceInput(device: captureDevice, error: &error)

    if error == nil && captureSession!.canAddInput(input) {
    captureSession!.addInput(input)

    stillImageOutput = AVCaptureStillImageOutput()
    stillImageOutput!.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
    if captureSession!.canAddOutput(stillImageOutput) {
        captureSession!.addOutput(stillImageOutput)

        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer!.videoGravity = AVLayerVideoGravityResizeAspect
        previewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.Portrait
        previewView.layer.addSublayer(previewLayer)

        captureSession!.startRunning()
    }
}

此外,另一个改进是使用自定义枚举来存储当前正在使用的相机而不是布尔值。这意味着您可以在以后添加它,比如是否有第三台相机。这看起来像:

enum CameraType {
    case front
    case back
}

var camera = CameraType.back

我希望这对您有所帮助,很抱歉省略了完整的代码示例,目前在 iPad 上,但我会在我使用计算机时进行更新。


更新

确保在更改相机之前从视图中删除之前的预览图层。

func reloadCamera() {
    captureSession?.stopRunning()
    previewLayer?.removeFromSuperlayer()

    // The rest of the camera loading code...

这应该可以解决您的相机冻结问题。