我正在尝试访问相机并在我的iPad应用程序中拍照,下面是适用于swift 1.2的代码,但在Swift 2中有3种类型的错误(在BLOCK注释中突出显示)失败。我花时间寻找快速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:方法不会覆盖其超类中的任何方法 for touchesBegan和touchesMoved
错误3:无法使用类型为'(device:AVCaptureDevice?,error:inout NSError?)的参数列表调用类型'AVCaptureDeviceInput'的初始值设定项。
更新:
所有其他问题都已修复(如果您正在寻找解决方案,请参考评论),除了以下一项。
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()
}
}
}
ERROR:
类型'()'不符合协议'BooleanType'
调用可以抛出,但没有标记为'try'并且未处理错误
答案 0 :(得分:4)
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?) {
}
答案 1 :(得分:1)
我在这里为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.
}
}