【问题标题】:Accessing Camera in Swift 2 iOS在 Swift 2 iOS 中访问相机
【发布时间】:2015-12-19 19:33:15
【问题描述】:

我正在尝试访问相机并在我的 iPad 应用程序中拍照,下面是适用于 swift 1.2 的代码,但在 Swift 2 中因 3 种类型的错误而失败(在 BLOCK cmets 下方突出显示)。我花了时间寻找 swift 2 的写作方式,但没有得到任何地方。任何建议都非常感谢。

import UIKit
import AVFoundation

class PictureController: UIViewController {
    
    let captureSession = AVCaptureSession()
    var previewLayer : AVCaptureVideoPreviewLayer?
    
    // If we find a device we'll store it here for later use
    var captureDevice : AVCaptureDevice?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view, typically from a nib.
        captureSession.sessionPreset = AVCaptureSessionPresetHigh
        
        let devices = AVCaptureDevice.devices()
        
        // Loop through all the capture devices on this phone
        for device in devices {
            // Make sure this particular device supports video
            if (device.hasMediaType(AVMediaTypeVideo)) {
                // Finally check the position and confirm we've got the back camera
                if(device.position == AVCaptureDevicePosition.Back) {
                    captureDevice = device as? AVCaptureDevice
                    if captureDevice != nil {
                        print("Capture device found")
                        beginSession()
                    }
                }
            }
        }
        
    }
    
    func focusTo(value : Float) {
        if let device = captureDevice {
            if(device.lockForConfiguration(nil)) { // CALL CAN THROW BUT IS NOT MARKED WITH 'TRY' AND THE ERROR IS NOT HANDLED
// nil IS NOT COMPATIBLE WITH EXPECTED ARGUMENT TYPE '()'
                device.setFocusModeLockedWithLensPosition(value, completionHandler: { (time) -> Void in
                    //
                })
                device.unlockForConfiguration()
            }
        }
    }
    
    let screenWidth = UIScreen.mainScreen().bounds.size.width
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { //METHOD DOES NOT OVERRIDE ANY METHOD FROM SUPERCLASS
        let anyTouch = touches.anyObject() as! UITouch
        let touchPercent = anyTouch.locationInView(self.view).x / screenWidth
        focusTo(Float(touchPercent))
    }
    
    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) { //METHOD DOES NOT OVERRIDE ANY METHOD FROM SUPERCLASS
        let anyTouch = touches.anyObject() as! UITouch
        let touchPercent = anyTouch.locationInView(self.view).x / screenWidth
        focusTo(Float(touchPercent))
    }
    
    func configureDevice() {
        if let device = captureDevice {
            device.lockForConfiguration(nil) // CALL CAN THROW BUT IS NOT MARKED WITH 'TRY' AND THE ERROR IS NOT HANDLED
// nil IS NOT COMPATIBLE WITH EXPECTED ARGUMENT TYPE '()'
            device.focusMode = .Locked
            device.unlockForConfiguration()
        }
        
    }
    
    func beginSession() {
        
        configureDevice()
        
        var err : NSError? = nil
        captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &err)) 
// Cannot invoke initializer for type 'AVCaptureDeviceInput' with an argument list of type '(device: AVCaptureDevice?, error: inout NSError?)'
        
        if err != nil {
            print("error: \(err?.localizedDescription)")
        }
        
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        self.view.layer.addSublayer(previewLayer)
        previewLayer?.frame = self.view.layer.frame
        captureSession.startRunning()
    }
    
    
}

错误1:调用可以抛出,但是没有标记'try'并且错误没有被处理 类型 '()' 不符合协议 'BooleanType'

错误 2:方法没有覆盖其超类中的任何方法 对于 touchesBegan 和 touchesMoved

错误 3:无法使用类型为“(设备:AVCaptureDevice?,错误:inout NSError?)”的参数列表调用类型“AVCaptureDeviceInput”的初始化程序

更新:

所有其他问题都已修复(如果您正在寻找解决方案,请参考 cmets),以下问题除外。

func focusTo(value : Float) {
        if let device = captureDevice {
            if(device.lockForConfiguration()) { // THIS LINE IS THROWING BELOW MENTIONED ERROR
                device.setFocusModeLockedWithLensPosition(value, completionHandler: { (time) -> Void in
                    
                })
                device.unlockForConfiguration()
            }
        }
    }

错误:

类型“()”不符合协议“BooleanType”

调用可以抛出,但是没有标记'try'并且错误没有处理

【问题讨论】:

  • 你试过运行 Swift 2 迁移器吗?
  • error3:只需添加尝试!在 AVCaptureDeviceInput 前面删除最后一个参数“, error: &err”
  • @AaronBrager 迁移器没有针对这些错误显示任何建议。当我尝试编译和构建时,编译器会突出显示出现上述错误的行。
  • @Rao 简单修复 如果您不想处理错误,那么对于 Xcode 7 的所有错误参数都是这样,否则您需要实现 do { try } catch { print(error)}
  • 如果您仍需要帮助,请告诉我,以便我重新提出问题

标签: ios swift swift2 xcode7 avcapturesession


【解决方案1】:
do {
    try device.lockForConfiguration()
    device.setFocusModeLockedWithLensPosition(value, completionHandler: { (time) -> Void in
                //
    })
    device.unlockForConfiguration()
} catch let error as NSError {
    print(error.code)
}


override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

}

【讨论】:

  • 有效,现在我正在尝试为 touchesBegan 和 touchesMoved 找出这个错误 Method does not override any method from its superclass
  • 做到了,现在扔了Method 'touchesBegan(_:withEvent:)' with Objective-C selector 'touchesBegan:withEvent:' conflicts with method 'touchesBegan(_:withEvent:)' from superclass 'UIResponder' with the same Objective-C selector
  • 您只需要在输入时让它自动完成。看看我的编辑。这个错误已经被问过很多次了。
  • 做到了,func touchesBegan(touches: Set&lt;UITouch&gt;, withEvent event: UIEvent?) { let touchPercent = touches.locationInView(self.view).x / screenWidth focusTo(Float(touchPercent)) } 现在抛出 Value of type 'Set&lt;UITouch&gt;' has no member 'locationInView'
  • 谢谢!现在我没有错误,但在我的模拟器中视图是空白页面。你知道任何演示如何在 Swift 2.0 中使用相机的教程吗?
【解决方案2】:

我在此处为 Swift2 发布了一个完整的解决方案,其中包含来自 gkhanacer https://stackoverflow.com/a/36719940/2144994 的解决方案以及此问题中的所有代码示例。这是一个完整的 ViewController

import UIKit
import AVFoundation

class FirstViewController: UIViewController {

let captureSession = AVCaptureSession()
var previewLayer : AVCaptureVideoPreviewLayer?

// If we find a device we'll store it here for later use
var captureDevice : AVCaptureDevice?

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view, typically from a nib.
    captureSession.sessionPreset = AVCaptureSessionPresetHigh

    let devices = AVCaptureDevice.devices()

    // Loop through all the capture devices on this phone
    for device in devices {
        // Make sure this particular device supports video
        if (device.hasMediaType(AVMediaTypeVideo)) {
            // Finally check the position and confirm we've got the back camera
            if(device.position == AVCaptureDevicePosition.Back) {
                captureDevice = device as? AVCaptureDevice
                if captureDevice != nil {
                    print("Capture device found")
                    beginSession()
                }
            }
        }
    }

}

let screenWidth = UIScreen.mainScreen().bounds.size.width

func configureDevice() {
    if let device = captureDevice {
        do {
        try device.lockForConfiguration()
        device.focusMode = .AutoFocus
        device.unlockForConfiguration()
        } catch let error as NSError {
            print(error.code)
        }
    }

}


override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    let screenSize = previewLayer!.bounds.size
    let frameSize:CGSize = view.frame.size
    if let touchPoint = touches.first {

        let location:CGPoint = touchPoint.locationInView(self.view)

        let x = location.x / frameSize.width
        let y = 1.0 - (location.x / frameSize.width)

        let focusPoint = CGPoint(x: x, y: y)

        print("POINT : X: \(x), Y: \(y)")


        let captureDevice = (AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! [AVCaptureDevice]).filter{$0.position == .Back}.first

        if let device = captureDevice {
            do {
                try device.lockForConfiguration()

                let support:Bool = device.focusPointOfInterestSupported

                if support  {

                    print("focusPointOfInterestSupported: \(support)")

                    device.focusPointOfInterest = focusPoint

                    // device.focusMode = .ContinuousAutoFocus
                    device.focusMode = .AutoFocus
                    // device.focusMode = .Locked

                    device.unlockForConfiguration()

                    print("Focus point was set successfully")
                }
                else{
                    print("focusPointOfInterestSupported is not supported: \(support)")
                }
            }
            catch {
                // just ignore
                print("Focus point error")
            }
        }
    }
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first{
        print("\(touch)")
    }
    super.touchesEnded(touches, withEvent: event)
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first{
        print("\(touch)")
    }
    super.touchesMoved(touches, withEvent: event)
}


func beginSession() {

    configureDevice()

    try! captureSession.addInput(AVCaptureDeviceInput(device: captureDevice))
    // Cannot invoke initializer for type 'AVCaptureDeviceInput' with an argument list of type '(device: AVCaptureDevice?, error: inout NSError?)'


    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    self.view.layer.addSublayer(previewLayer!)
    previewLayer?.frame = self.view.layer.frame
    captureSession.startRunning()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-27
    • 2010-09-09
    • 1970-01-01
    • 2021-10-18
    • 2019-02-23
    • 1970-01-01
    • 2017-10-31
    • 2012-08-26
    相关资源
    最近更新 更多