簡體   English   中英

我如何從 PHPickerResult 獲取 PHAsset? iOS 14

[英]How can i get PHAsset from PHPickerResult? iOS 14

所以,我發現之前問過類似的問題,但是當我嘗試與我得到的相同的方式時,它並沒有像我預期的那樣工作,所以我想做的是,我想從 PHPickerViewController 的 PHPickerResult 獲取 PHAsset。

所以使用這個源代碼作為我的基本代碼進行試驗,並將它與我從中得到的結合起來

當我嘗試這個時,也已經將“隱私 - 照片庫使用說明”添加到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)
                        }
                    }
                }
            }
        }
    }
  }
}

用法:

在視圖 controller 中初始化一個變量:

let imagePicker = ImagePickerManager()

在按鈕操作上粘貼此行

ImagePickerManager().pickSingleImage(self) { pickedImage in
        self.myImageView.image = pickedImage
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM