ios – 如何在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...

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

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...