如何在Swift中使用UIImagePickerController捕获相机?

37

我试图在Swift中使用UIImagePickerController,但它不起作用...

我的ViewController:

class ViewController: UIViewController {

@IBOutlet var imag : UIView = nil
@IBAction func capture(sender : UIButton) {
    println("Button capture")
    if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)
    {
        var imag = UIImagePickerController()
        imag.delegate = self
        imag.sourceType = UIImagePickerControllerSourceType.Camera;
       imag.mediaTypes = kUTTypeImage
        imag.allowsEditing = false

        self.presentViewController(imag, animated: true, completion: nil)

    }
   }   
}

我在以下代码行中遇到了错误

imag.delegate = self 
(Type'ViewControlles does confoorm to protocol 'UIImagePickerControllerDelegate')
imagePicker.mediaTypes = kUTTypeImage   
(use of unresolved identifier kUTTypeImage)

我读到过在Swift中不能使用kUTTypeImage,但不确定,我可能使用这些函数不正确。有人能帮忙吗?

谢谢!!


1
我发现了这个链接:http://beefdev.blogspot.com/2012/02/use-of-undeclared-identifier.html基本上它说明你需要将MobileCoreServices.framework链接到你的二进制文件中,然后在你使用的类中作为一个框架进行导入。这解决了我的问题。 - Morkrom
7个回答

84

在控制器中还应导入MobileCoreServices:

import MobileCoreServices 

然后将类型放在方括号内,就像这样:

image.mediaTypes = [kUTTypeImage]

Swift 2.0及以上版本

image.mediaTypes = [kUTTypeImage as String]

3
谢谢!我刚花了一个小时试图理解那个“未解决的引用”编译错误...!! - Sébastien Stormacq
谢谢,我无法使用桥接头和#import <MobileCoreServices/UTCoreTypes.h>使其工作(对于其他人阅读此内容:不要尝试那样做)。 - ephemer
请注意,kUTTypeImage 是 CFString,而 mediaTypes 需要一个字符串。为此,您需要使用 imag.mediaTypes = [kUTTypeImage as String] - Matthew Cawley

43

Swift 2.0

In Swift 2.0 (Xcode 7), 您需要将kUTTypeImage(一个CFString)显式转换为String

picker.mediaTypes = [kUTTypeImage as String]

而且您仍需要导入Mobile Core Services才能定义此符号:

import MobileCoreServices 

话虽如此,mediaTypes 的默认值为[kUTTypeImage],所以如果这正是你想要的,你就不需要设置它。


1
在未来默认值发生变化的情况下,明确允许仅图像不是一个好的实践吗? - Crashalot

24

此外,您还应将UINavigationControllerDelegate添加到ViewController的协议列表中,并且如果您计划获取图片,则需要添加其中一个可选的代理函数。

这是解决您问题的可行代码:

import UIKit
import MobileCoreServices

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!){
        println("i've got an image");
    }

    @IBAction func capture(sender : UIButton) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera){
            println("Button capture")

            var imag = UIImagePickerController()
            imag.delegate = self
            imag.sourceType = UIImagePickerControllerSourceType.Camera;
            imag.mediaTypes = [kUTTypeImage]
            imag.allowsEditing = false

            self.presentViewController(imag, animated: true, completion: nil)
        }
    }
}

Roman,请问您能否确认Beta3版本对您有效?我在kUTTypeImage引用方面遇到了一些问题。谢谢。 - Narwhal
2
在Beta5中,imag.mediaTypes=[kUTTypeImage]会导致错误。将其更改为imagePicker.mediaTypes = NSArray(object: kUTTypeImage),它就可以正常工作了。 - ohyes
你可以在这里找到一个修改后的代码版本,它可以在Beta 6中运行:http://pastebin.com/5RxLDw0f - Apfelsaft
@ohyes 你说得对。即使在 Xcode 6.0.1 中,你也需要输入 mediaTypes = NSArray(object: kUTTypeImage)。将其设置为普通的 Swift 数组会导致崩溃。 - Salman Hasrat Khan
你还需要将MobileCoreServices添加到“链接二进制文件和库”中。 - Adrian
显示剩余2条评论

7

根据您的代码,很明显您在两个地方犯了错误,一个是设置delegate,另一个是设置媒体类型imag.mediaTypes = kUTTypeImage

第一个问题:如果您查看UIImagePickerControllerdelegate定义,它需要确认两个协议UINavigationControllerDelegateUIImagePickerControllerDelegate,因此您必须在viewcontroller类中采用这两个协议,就像这样:

class ViewController: UIViewController,UINavigationControllerDelegate,    UIImagePickerControllerDelegate

第二个错误:如果你查看 mediaTypes 的定义部分,它明确要求传递媒体类型数组,请按照以下方式操作。
imag.mediaTypes = [kUTTypeImage]

除此之外,我已经写了一个非常好的类来完成同样的任务。这个类容易理解和整合。请点击这里
//Declare property 
var imagePicker:ImageVideoPicker?

//Call below line of code properly, it will return an image

self.imagePicker = ImageVideoPicker(frame: self.view.frame, superVC: self) { (capturedImage) -> Void in
        if let captureImage = capturedImage{
        //you did it.....

        }

    }

请问您能否在向下转换我的答案之前给出原因。我很乐意知道。 - Kamar Shad
我不知道为什么人们这么匆忙,即使他们不试图思考,我们在这里是互相帮助的。我请求大家,在你们进行任何负面评价时,请在评论中说明原因。这将有助于我和其他人。 - Kamar Shad
2
我认为你应该更清楚地表明ImageVideoPicker是你自己的类。我没有给你投反对票,但我确实浪费了时间检查ImageVideoPicker是否是一种新的仅限于Swift的类或者其他什么东西。 - ephemer
3
你要求我解释,而现在你却因为我提供了解释而轻视我。高雅。 - ephemer

2
你必须按照代表的要求去做。
 class ViewController: UIViewController, UIImagePickerControllerDelegate

根据文档,媒体类型默认设置为图像,因此您可以继续删除该行,因为您仅将其设置为图像。
不要忘记实现文档中概述的协议方法: documentation

但是 imag.mediaTypes = [kUTTypeImage as String],在 Swift 中存在 kUTTypeImage 吗?还是有其他的方法可以调用相机? - user3745888

2

试试这个

import UIKit
import AVFoundation

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var imagePicker: UIImagePickerController!

@IBOutlet weak var ImageView: UIImageView!



override func viewDidLoad() {
    super.viewDidLoad()


}

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

@IBAction func takeImage(sender: AnyObject) {

    imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = .Camera
    presentViewController(imagePicker, animated: true, completion: nil)

}


func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    imagePicker.dismissViewControllerAnimated(true, completion: nil)
    ImageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
}

}

0

Swift 1.2 语法:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
        let image = info[UIImagePickerControllerOriginalImage]



    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接