我如何从 PHPickerResult 获取 PHAsset? iOS 14
How can i get PHAsset from PHPickerResult? iOS 14
所以,我发现之前问过类似的问题,但是当我尝试与我得到的相同的方式时,它并没有像我预期的那样工作,所以我想做的是,我想从来自 PHPickerViewController 的 PHPickerResult。
所以用这个 source as my base code, and combined it with what I got from this 进行试验。
也已经添加
《隐私-图片库使用说明》
当我尝试这个时 info.plist
。
代码如下所示。
import UIKit
import PhotosUI
class ViewController: UIViewController {
@IBOutlet weak var myImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func buttonDidTap(_ sender: Any) {
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 1
configuration.filter = .any(of: [.images, .videos])
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
self.present(picker, animated: true, completion: nil)
}
}
extension ViewController: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
let identifiers = results.compactMap(\.assetIdentifier)
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
fetchResult.enumerateObjects { (asset, index, stop) -> Void in
PHImageManager.default().requestImage(for: asset,
targetSize: CGSize.init(width: 20, height: 20),
contentMode: PHImageContentMode.aspectFit,
options: nil) { (image: UIImage?, _: [AnyHashable : Any]?) in
self.myImageView.image = image
}
}
}
}
调试代码后,发现fetchResult.enumerateObjects
里面的代码没有被调用,所以无法获取图像。
或者我的语法有误?有人可以帮助我吗?
如果您稍后需要资产,则必须使用照片库初始化配置。所以这一行是错误的:
var configuration = PHPickerConfiguration()
你想要:
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
matt 可能说得对,但您还可以做以下事情。这样,图片将直接显示在 UIImageView 中,配置与您所做的相同。
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
dismiss(animated: true)
let itemProviders = results.map(\.itemProvider)
for item in itemProviders {
if item.canLoadObject(ofClass: UIImage.self) {
item.loadObject(ofClass: UIImage.self) { (image, error) in
DispatchQueue.main.async {
if let image = image as? UIImage {
self.myImageView.image = image
}
}
}
}
}
}
您可以使用这个自定义 class ImagePickerManager:
import Foundation
import UIKit
import PhotosUI
class ImagePickerManager: NSObject, PHPickerViewControllerDelegate, UINavigationControllerDelegate {
var picker: PHPickerViewController?
var pickImageCallback : ((UIImage) -> ())?
var viewController: UIViewController?
override init(){
super.init()
}
func pickSingleImage(_ viewController: UIViewController, _ callback: @escaping ((UIImage) -> ())) {
pickImageCallback = callback
self.viewController = viewController
var configuration = PHPickerConfiguration()
configuration.filter = .any(of: [.images, .livePhotos])
configuration.selectionLimit = 1
picker = PHPickerViewController(configuration: configuration)
picker?.delegate = self
viewController.present(picker!, animated: true, completion: nil)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true) {
let itemProviders = results.map(\.itemProvider)
for item in itemProviders {
if item.canLoadObject(ofClass: UIImage.self) {
item.loadObject(ofClass: UIImage.self) { (image, error) in
DispatchQueue.main.async {
if let image = image as? UIImage {
self.pickImageCallback!(image)
}
}
}
}
}
}
}
}
用法:
在视图控制器中初始化一个变量:
let imagePicker = ImagePickerManager()
在按钮操作上粘贴此行
ImagePickerManager().pickSingleImage(self) { pickedImage in
self.myImageView.image = pickedImage
}
所以,我发现之前问过类似的问题,但是当我尝试与我得到的相同的方式时,它并没有像我预期的那样工作,所以我想做的是,我想从来自 PHPickerViewController 的 PHPickerResult。
所以用这个 source as my base code, and combined it with what I got from this 进行试验。
也已经添加
《隐私-图片库使用说明》
当我尝试这个时 info.plist
。
代码如下所示。
import UIKit
import PhotosUI
class ViewController: UIViewController {
@IBOutlet weak var myImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func buttonDidTap(_ sender: Any) {
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 1
configuration.filter = .any(of: [.images, .videos])
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
self.present(picker, animated: true, completion: nil)
}
}
extension ViewController: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
let identifiers = results.compactMap(\.assetIdentifier)
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
fetchResult.enumerateObjects { (asset, index, stop) -> Void in
PHImageManager.default().requestImage(for: asset,
targetSize: CGSize.init(width: 20, height: 20),
contentMode: PHImageContentMode.aspectFit,
options: nil) { (image: UIImage?, _: [AnyHashable : Any]?) in
self.myImageView.image = image
}
}
}
}
调试代码后,发现fetchResult.enumerateObjects
里面的代码没有被调用,所以无法获取图像。
或者我的语法有误?有人可以帮助我吗?
如果您稍后需要资产,则必须使用照片库初始化配置。所以这一行是错误的:
var configuration = PHPickerConfiguration()
你想要:
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
matt 可能说得对,但您还可以做以下事情。这样,图片将直接显示在 UIImageView 中,配置与您所做的相同。
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
dismiss(animated: true)
let itemProviders = results.map(\.itemProvider)
for item in itemProviders {
if item.canLoadObject(ofClass: UIImage.self) {
item.loadObject(ofClass: UIImage.self) { (image, error) in
DispatchQueue.main.async {
if let image = image as? UIImage {
self.myImageView.image = image
}
}
}
}
}
}
您可以使用这个自定义 class ImagePickerManager:
import Foundation
import UIKit
import PhotosUI
class ImagePickerManager: NSObject, PHPickerViewControllerDelegate, UINavigationControllerDelegate {
var picker: PHPickerViewController?
var pickImageCallback : ((UIImage) -> ())?
var viewController: UIViewController?
override init(){
super.init()
}
func pickSingleImage(_ viewController: UIViewController, _ callback: @escaping ((UIImage) -> ())) {
pickImageCallback = callback
self.viewController = viewController
var configuration = PHPickerConfiguration()
configuration.filter = .any(of: [.images, .livePhotos])
configuration.selectionLimit = 1
picker = PHPickerViewController(configuration: configuration)
picker?.delegate = self
viewController.present(picker!, animated: true, completion: nil)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true) {
let itemProviders = results.map(\.itemProvider)
for item in itemProviders {
if item.canLoadObject(ofClass: UIImage.self) {
item.loadObject(ofClass: UIImage.self) { (image, error) in
DispatchQueue.main.async {
if let image = image as? UIImage {
self.pickImageCallback!(image)
}
}
}
}
}
}
}
}
用法:
在视图控制器中初始化一个变量:
let imagePicker = ImagePickerManager()
在按钮操作上粘贴此行
ImagePickerManager().pickSingleImage(self) { pickedImage in
self.myImageView.image = pickedImage
}