web-dev-qa-db-fra.com

Swift - UIImagePickerController - comment l’utiliser?

J'essaie de comprendre comment cela fonctionne, mais c'est assez difficile pour moi. =) J'ai 1 vue, il y a un bouton et une petite zone ImageView pour la prévisualisation. Le bouton déclenche imagepickercontroller, et UIView affichera l’image sélectionnée. Il n'y a pas d'erreur mais l'image ne s'affiche pas dans la zone 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)
}
40
user3806731

Vous prenez un UIImage nommé UIImagePickerControllerOriginalImage et il n’existe pas d’image de ce type. Vous êtes censé saisir le UIImage avec la clé UIImagePickerControllerOriginalImage du dictionnaire editingInfo:

let tempImage = editingInfo[UIImagePickerControllerOriginalImage] as! UIImage
35
Jesper
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)    
   }
 }
24

Détails

  • Xcode 10.2 (10E125), Swift 5

Plus

Comment construire son propre sélecteur de photo

Solution

import AVFoundation
import Photos

protocol ImagePickerDelegate: class {
    func imagePickerDelegate(canUseCamera accessIsAllowed: Bool, delegatedForm: ImagePicker)
    func imagePickerDelegate(canUseGallery accessIsAllowed: Bool, delegatedForm: ImagePicker)
    func imagePickerDelegate(didSelect image: UIImage, delegatedForm: ImagePicker)
    func imagePickerDelegate(didCancel delegatedForm: ImagePicker)
}

class ImagePicker: NSObject {

    private weak var controller: UIImagePickerController?
    weak var delegate: ImagePickerDelegate? = 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)
        }
    }

    func dismiss() { controller?.dismiss(animated: true, completion: nil) }
}

extension ImagePicker {

    private func showAlert(targetName: String, completion: @escaping (Bool)->()) {
        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.delegate?.window??.rootViewController?.present(alertVC, animated: true, completion: nil)
        }
    }

    func cameraAsscessRequest() {
        if AVCaptureDevice.authorizationStatus(for: .video) ==  .authorized {
            delegate?.imagePickerDelegate(canUseCamera: true, delegatedForm: self)
        } else {
            AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in
                guard let self = self else { return }
                if granted {
                    self.delegate?.imagePickerDelegate(canUseCamera: granted, delegatedForm: self)
                } else {
                    self.showAlert(targetName: "camera") { self.delegate?.imagePickerDelegate(canUseCamera: $0, delegatedForm: self) }
                }
            }
        }
    }

    func photoGalleryAsscessRequest() {
        PHPhotoLibrary.requestAuthorization { [weak self] result in
            guard let self = self else { return }
            if result == .authorized {
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    self.delegate?.imagePickerDelegate(canUseGallery: result == .authorized, delegatedForm: self)
                }
            } else {
                self.showAlert(targetName: "photo gallery") { self.delegate?.imagePickerDelegate(canUseCamera: $0, delegatedForm: self) }
            }
        }
    }
}

extension ImagePicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

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

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

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        delegate?.imagePickerDelegate(didCancel: self)
    }
}

Utilisation complète

Info.plist

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

ViewController (n'oubliez pas de coller le code de la solution)

import UIKit

class ViewController: UIViewController {

    private lazy var imagePicker = ImagePicker()

    private weak var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        imagePicker.delegate = self

        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
    }

    private func presentImagePicker(sourceType: UIImagePickerController.SourceType) {
        imagePicker.present(parent: self, sourceType: sourceType)
    }

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

extension ViewController: ImagePickerDelegate {

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

    func imagePickerDelegate(didCancel delegatedForm: ImagePicker) { imagePicker.dismiss() }

    func imagePickerDelegate(canUseGallery accessIsAllowed: Bool, delegatedForm: ImagePicker) {
        if accessIsAllowed { presentImagePicker(sourceType: .photoLibrary) }
    }

    func imagePickerDelegate(canUseCamera accessIsAllowed: Bool, delegatedForm: ImagePicker) {
        // works only on real device (crash on simulator)
        if accessIsAllowed { presentImagePicker(sourceType: .camera) }
    }
}

Images

enter image description here


enter image description here


enter image description here


enter image description here


enter image description here


enter image description here

20
Vasily Bodnarchuk

Depuis Swift 4.2 et xcode 10 la func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) changer un peu.

dans l'en-tête de la fonction, la section infoKey change de

didFinishPickingMediaWithInfo info: [String : Any] à

didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]

Pour obtenir l'image originale, vous devez maintenant appeler:

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

let image = info[.originalImage] as? UIImage

trouver d'autres infoKeys ici (editéImage, imageURL et plus ...)

9
andre_hold

Essaye ça:

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

ou vous pouvez aussi utiliser ? au lieu de !.

4
Gaurav