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 8.3, Swift 3.1
Code
ImagePicker
import AVFoundation
import Photos
class ImagePicker: NSObject {
var controller = UIImagePickerController()
var selectedImage: UIImage?
var delegate: ImagePickerDelegate? = nil
override init() {
super.init()
controller.sourceType = .photoLibrary
controller.delegate = self
}
func dismiss() {
controller.dismiss(animated: true, completion: nil)
}
}
extension ImagePicker {
func cameraAsscessRequest() {
if AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) == AVAuthorizationStatus.authorized {
delegate?.imagePickerDelegate(canUseCamera: true, delegatedForm: self)
} else {
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted -> Void in
self.delegate?.imagePickerDelegate(canUseCamera: granted, delegatedForm: self)
}
}
}
func galleryAsscessRequest() {
PHPhotoLibrary.requestAuthorization { [weak self] result in
if let _self = self {
var access = false
if result == .authorized {
access = true
}
_self.delegate?.imagePickerDelegate(canUseGallery: access, delegatedForm: _self)
}
}
}
}
extension ImagePicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let imageName = "img_\(Date().timeIntervalSince1970)"
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
delegate?.imagePickerDelegate(didSelect: image, imageName: imageName, delegatedForm: self)
}
else if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
delegate?.imagePickerDelegate(didSelect: image, imageName: imageName, delegatedForm: self)
} else{
print("Something went wrong")
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
delegate?.imagePickerDelegate(didCancel: self)
}
}
ImagePickerDelegate
import UIKit
protocol ImagePickerDelegate {
func imagePickerDelegate(canUseCamera accessIsAllowed:Bool, delegatedForm: ImagePicker)
func imagePickerDelegate(canUseGallery accessIsAllowed:Bool, delegatedForm: ImagePicker)
func imagePickerDelegate(didSelect image: UIImage, imageName:String, delegatedForm: ImagePicker)
func imagePickerDelegate(didCancel delegatedForm: ImagePicker)
}
extension ImagePickerDelegate {
func imagePickerDelegate(canUseCamera accessIsAllowed:Bool, delegatedForm: ImagePicker) {}
func imagePickerDelegate(canUseGallery accessIsAllowed:Bool, delegatedForm: ImagePicker) {}
}
Usage
Info.plist
ADD:
<key>NSPhotoLibraryUsageDescription</key>
<string>bla-bla-bla</string>
<key>NSCameraUsageDescription</key>
<string>bla-bla-bla</string>
ViewController
import UIKit
class ViewController: UIViewController {
fileprivate var imagePicker = ImagePicker()
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
fileprivate func presentImagePicker(sourceType: UIImagePickerControllerSourceType) {
imagePicker.controller.sourceType = sourceType
DispatchQueue.main.async {
self.present(self.imagePicker.controller, animated: true, completion: nil)
}
}
@IBAction func presentPickerAndRequestPermission(_ sender: UIButton) {
presentImagePicker(sourceType: .savedPhotosAlbum)
}
@IBAction func requestPermissionAndPresentPicker(_ sender: UIButton) {
imagePicker.galleryAsscessRequest()
}
@IBAction func cameraButtonTapped(_ sender: Any) {
imagePicker.cameraAsscessRequest()
}
}
extension ViewController: ImagePickerDelegate {
func imagePickerDelegate(didSelect image: UIImage, imageName:String, 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) {
if accessIsAllowed {
// works only on real device (crash on simulator)
presentImagePicker(sourceType: .camera)
}
}
}
Main.storyboard
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12118" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="8h3-th-UId">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_43425753" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="lOV-da-uaY">
<rect key="frame" x="67" y="269" width="240" height="128"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="128" id="iv7-J9-AJp"/>
<constraint firstAttribute="width" constant="240" id="pOJ-T3-hG6"/>
</constraints>
</imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="f1v-ZZ-Ymw">
<rect key="frame" x="16" y="231" width="343" height="30"/>
<state key="normal" title="Request permission before present picker"/>
<connections>
<action selector="requestPermissionAndPresentPicker:" destination="BYZ-38-t0r" eventType="touchUpInside" id="lyc-yI-9TS"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="41F-AZ-10t">
<rect key="frame" x="16" y="193" width="343" height="30"/>
<state key="normal" title="Present picker before request permission"/>
<connections>
<action selector="presentPickerAndRequestPermission:" destination="BYZ-38-t0r" eventType="touchUpInside" id="Wfy-u3-9Xi"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="f1v-ZZ-Ymw" firstAttribute="top" secondItem="41F-AZ-10t" secondAttribute="bottom" constant="8" symbolic="YES" id="H79-n9-dbA"/>
<constraint firstItem="lOV-da-uaY" firstAttribute="top" secondItem="f1v-ZZ-Ymw" secondAttribute="bottom" constant="8" symbolic="YES" id="QEf-Il-7CA"/>
<constraint firstItem="41F-AZ-10t" firstAttribute="leading" secondItem="f1v-ZZ-Ymw" secondAttribute="leading" id="T9O-9X-o17"/>
<constraint firstItem="f1v-ZZ-Ymw" firstAttribute="centerX" secondItem="lOV-da-uaY" secondAttribute="centerX" id="YEX-d4-Ktl"/>
<constraint firstItem="41F-AZ-10t" firstAttribute="trailing" secondItem="f1v-ZZ-Ymw" secondAttribute="trailing" id="b0d-Z3-EPR"/>
<constraint firstItem="lOV-da-uaY" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="fjW-qF-w9E"/>
<constraint firstItem="lOV-da-uaY" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="paK-zP-Zny"/>
<constraint firstItem="41F-AZ-10t" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" id="wOA-e7-6ND"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="O38-0b-A9f">
<barButtonItem key="leftBarButtonItem" systemItem="camera" id="T6B-k6-KJ9">
<connections>
<action selector="cameraButtonTapped:" destination="BYZ-38-t0r" id="OBY-pO-8HL"/>
</connections>
</barButtonItem>
</navigationItem>
<connections>
<outlet property="imageView" destination="lOV-da-uaY" id="EYi-qU-noP"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1013.6" y="-579.76011994002999"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="BZr-BH-sMY">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="8h3-th-UId" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="J5d-TE-5r7">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="UWM-bm-ZNP"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Hzd-Nh-WhC" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="125.59999999999999" y="-578.86056971514245"/>
</scene>
</scenes>
</document>
Results
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 !
.