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. The button triggers imagepickercontroller, and the UIView will display picked image. There is no error but the image doesn't show in the UIImageView area.
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. You're meant to grab the UIImage with the key UIImagePickerControllerOriginalImage from the editingInfo dictionary:
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)
}
}
Details
- Xcode 10.2 (10E125), Swift 5
More
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)
}
}
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)
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
Since swift 4.2 and xcode 10 the func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) change a bit.
at the function header the infoKey-Section changes from
didFinishPickingMediaWithInfo info: [String : Any] to
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]
To get the originalImage you now have to call:
let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage or
let image = info[.originalImage] as? UIImage
find other infoKeys here (editedImage, imageURL and more...)
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 !.
来源:https://stackoverflow.com/questions/24625687/swift-uiimagepickercontroller-how-to-use-it





