简体   繁体   English

Swift - UIImagePickerController - 如何使用它?

[英]Swift - UIImagePickerController - how to use it?

I am trying hard to understand how this works, but it's pretty hard for me.我正在努力理解这是如何工作的,但这对我来说很难。 =) I have 1 view, there is one button and one small ImageView area for preview. =) 我有 1 个视图,有一个按钮和一个用于预览的小 ImageView 区域。 The button triggers imagepickercontroller, and the UIView will display picked image.该按钮触发 imagepickercontroller,UIView 将显示拾取的图像。 There is no error but the image doesn't show in the UIImageView area.没有错误,但图像未显示在 UIImageView 区域中。

var imagePicker = UIImagePickerController()
@IBOutlet var imagePreview : UIImageView

@IBAction func AddImageButton(sender : AnyObject) {
    imagePicker.modalPresentationStyle = UIModalPresentationStyle.CurrentContext
    imagePicker.delegate = self
    self.presentModalViewController(imagePicker, animated: true)

}
func imagePickerController(picker: UIImagePickerController!, didFinishPickingMediaWithInfo info:NSDictionary!) {
    var tempImage:UIImage = info[UIImagePickerControllerOriginalImage] as UIImage
    imagePreview.image  = tempImage

    self.dismissModalViewControllerAnimated(true)

}

func imagePickerControllerDidCancel(picker: UIImagePickerController!) {

    self.dismissModalViewControllerAnimated(true)
}

You're grabbing a UIImage named UIImagePickerControllerOriginalImage and there exists no such image.您正在抓取一个名为UIImagePickerControllerOriginalImageUIImage并且不存在这样的图像。 You're meant to grab the UIImage with the key UIImagePickerControllerOriginalImage from the editingInfo dictionary:您打算使用来自editingInfo字典的键UIImagePickerControllerOriginalImage获取UIImage

let tempImage = editingInfo[UIImagePickerControllerOriginalImage] as! UIImage

Details细节

  • Xcode 11.4.1 (11E503a), Swift 5.2 Xcode 11.4.1 (11E503a),Swift 5.2

More更多的

How to build own photo picker如何构建自己的照片选择器

Solution解决方案

import UIKit
import AVFoundation
import Photos

protocol ImagePickerDelegate: class {
    func imagePicker(_ imagePicker: ImagePicker, grantedAccess: Bool,
                     to sourceType: UIImagePickerController.SourceType)
    func imagePicker(_ imagePicker: ImagePicker, didSelect image: UIImage)
    func cancelButtonDidClick(on imageView: ImagePicker)
}

class ImagePicker: NSObject {

    private weak var controller: UIImagePickerController?
    weak var delegate: ImagePickerDelegate? = nil

    func dismiss() { controller?.dismiss(animated: true, completion: nil) }
    func present(parent viewController: UIViewController, sourceType: UIImagePickerController.SourceType) {
        let controller = UIImagePickerController()
        controller.delegate = self
        controller.sourceType = sourceType
        self.controller = controller
        DispatchQueue.main.async {
            viewController.present(controller, animated: true, completion: nil)
        }
    }
}

// MARK: Get access to camera or photo library

extension ImagePicker {

    private func showAlert(targetName: String, completion: ((Bool) -> Void)?) {
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            let alertVC = UIAlertController(title: "Access to the \(targetName)",
                                            message: "Please provide access to your \(targetName)",
                                            preferredStyle: .alert)
            alertVC.addAction(UIAlertAction(title: "Settings", style: .default, handler: { action in
                guard   let settingsUrl = URL(string: UIApplication.openSettingsURLString),
                        UIApplication.shared.canOpenURL(settingsUrl) else { completion?(false); return }
                UIApplication.shared.open(settingsUrl, options: [:]) { [weak self] _ in
                    self?.showAlert(targetName: targetName, completion: completion)
                }
            }))
            alertVC.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in completion?(false) }))
            UIApplication.shared.windows.filter { $0.isKeyWindow }.first?
                .rootViewController?.present(alertVC, animated: true, completion: nil)
        }
    }

    func cameraAsscessRequest() {
        if delegate == nil { return }
        let source = UIImagePickerController.SourceType.camera
        if AVCaptureDevice.authorizationStatus(for: .video) ==  .authorized {
            delegate?.imagePicker(self, grantedAccess: true, to: source)
        } else {
            AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in
                guard let self = self else { return }
                if granted {
                    self.delegate?.imagePicker(self, grantedAccess: granted, to: source)
                } else {
                    self.showAlert(targetName: "camera") { self.delegate?.imagePicker(self, grantedAccess: $0, to: source) }
                }
            }
        }
    }

    func photoGalleryAsscessRequest() {
        PHPhotoLibrary.requestAuthorization { [weak self] result in
            guard let self = self else { return }
            let source = UIImagePickerController.SourceType.photoLibrary
            if result == .authorized {
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    self.delegate?.imagePicker(self, grantedAccess: result == .authorized, to: source)
                }
            } else {
                self.showAlert(targetName: "photo gallery") { self.delegate?.imagePicker(self, grantedAccess: $0, to: source) }
            }
        }
    }
}

// MARK: UINavigationControllerDelegate

extension ImagePicker: UINavigationControllerDelegate { }

// MARK: UIImagePickerControllerDelegate

extension ImagePicker: UIImagePickerControllerDelegate {

    func imagePickerController(_ picker: UIImagePickerController,
                               didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let image = info[.editedImage] as? UIImage {
            delegate?.imagePicker(self, didSelect: image)
            return
        }

        if let image = info[.originalImage] as? UIImage {
            delegate?.imagePicker(self, didSelect: image)
        } else {
            print("Other source")
        }
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        delegate?.cancelButtonDidClick(on: self)
    }
}

Full Usage完全使用

Info.plist信息表

 <key>NSPhotoLibraryUsageDescription</key>
 <string>bla-bla-bla</string>
 <key>NSCameraUsageDescription</key>
 <string>bla-bla-bla</string>

ViewController (do not forget to paste solution code) ViewController (不要忘记粘贴解决方案代码)

import UIKit

class ViewController: UIViewController {

    private weak var imageView: UIImageView!
    private lazy var imagePicker: ImagePicker = {
        let imagePicker = ImagePicker()
        imagePicker.delegate = self
        return imagePicker
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "camera", style: .plain, target: self,
                                                           action: #selector(cameraButtonTapped))
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "photo", style: .plain, target: self,
                                                           action: #selector(photoButtonTapped))

        let imageView = UIImageView(frame: CGRect(x: 40, y: 80, width: 200, height: 200))
        imageView.backgroundColor = .lightGray
        view.addSubview(imageView)
        self.imageView = imageView
    }

    @objc func photoButtonTapped(_ sender: UIButton) { imagePicker.photoGalleryAsscessRequest() }
    @objc func cameraButtonTapped(_ sender: UIButton) { imagePicker.cameraAsscessRequest() }
}

// MARK: ImagePickerDelegate

extension ViewController: ImagePickerDelegate {

    func imagePicker(_ imagePicker: ImagePicker, didSelect image: UIImage) {
        imageView.image = image
        imagePicker.dismiss()
    }

    func cancelButtonDidClick(on imageView: ImagePicker) { imagePicker.dismiss() }
    func imagePicker(_ imagePicker: ImagePicker, grantedAccess: Bool,
                     to sourceType: UIImagePickerController.SourceType) {
        guard grantedAccess else { return }
        imagePicker.present(parent: self, sourceType: sourceType)
    }
}

Images图片

在此处输入图片说明


在此处输入图片说明


在此处输入图片说明


在此处输入图片说明


在此处输入图片说明


在此处输入图片说明

import MobileCoreServices

class SecondViewController: UIViewController,UINavigationControllerDelegate, UIImagePickerControllerDelegate {

   @IBOutlet var img:UIImageView!=nil

   override func viewDidLoad() {
        super.viewDidLoad()
   }

   override func didReceiveMemoryWarning() 
   {
       super.didReceiveMemoryWarning()

   }

   @IBAction func buttonTapped(AnyObject)
   {
     if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary){
            println("Button capture")
            var imag = UIImagePickerController()
            imag.delegate = self
            imag.sourceType = UIImagePickerControllerSourceType.PhotoLibrary;
            //imag.mediaTypes = [kUTTypeImage];
            imag.allowsEditing = false
            self.presentViewController(imag, animated: true, completion: nil)
        }
   }

   func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) {
        let selectedImage : UIImage = image
       //var tempImage:UIImage = editingInfo[UIImagePickerControllerOriginalImage] as UIImage
        img.image=selectedImage
        self.dismissViewControllerAnimated(true, completion: nil)    
   }
 }

Since swift 4.2 and xcode 10 the func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) change a bit.swift 4.2xcode 10 开始func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])发生了一些变化。

at the function header the infoKey-Section changes from在函数头处,infoKey-Section 从

didFinishPickingMediaWithInfo info: [String : Any] to didFinishPickingMediaWithInfo info: [String : Any]

didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]

To get the originalImage you now have to call:要获得 originalImage,您现在必须调用:

let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage or let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage

let image = info[.originalImage] as? UIImage

find other infoKeys here (editedImage, imageURL and more...) 在此处查找其他信息键(editedImage、imageURL 等...)

Try this:尝试这个:

func imagePickerController(picker: UIImagePickerController!, didFinishPickingMediaWithInfo info:NSDictionary!) {
    let tempImage = info[UIImagePickerControllerOriginalImage] as! UIImage
    imagePreview.image  = tempImage

or you can also use ?或者你也可以使用? in place of !代替! . .

In Swift 5.2, iOS 14.2在 Swift 5.2、iOS 14.2 中

class YourViewController: UIViewController,UINavigationControllerDelegate, UIImagePickerControllerDelegate {

@IBAction func btnTapped(_ sender: Any) {
    let imagePickerController = UIImagePickerController()
    imagePickerController.allowsEditing = false //If you want edit option set "true"
    imagePickerController.sourceType = .photoLibrary
    imagePickerController.delegate = self
    present(imagePickerController, animated: true, completion: nil)
    
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let tempImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
    imgRoom.image  = tempImage
    self.dismiss(animated: true, completion: nil)
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    dismiss(animated: true, completion: nil)
}

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM