Swift - UIImagePickerController - how to use it?

2019-01-17 03:36发布

问题:

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)
}

回答1:

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


回答2:

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)    
   }
 }


回答3:

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



回答4:

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...)



回答5:

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 !.