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)
}
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
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)
}
}
Comment construire son propre sélecteur de photo
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)
}
}
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) }
}
}
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 ...)
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 !
.