简体   繁体   English

我可以设置图像的顺序吗? PHPickerViewController

[英]Can I set the order of the images? PHPickerViewController

Using the PHPickerViewController, the result of the selected image will be displayed as a result.使用 PHPickerViewController,选择图像的结果将显示为结果。 Can I set the order of the images?我可以设置图像的顺序吗?

private func makePickerViewController(selectionLimit: Int) -> PHPickerViewController {
    var config = PHPickerConfiguration()
    config.selectionLimit = selectionLimit
    config.filter = PHPickerFilter.images
    
    let pickerViewController =  PHPickerViewController(configuration: config)
    return pickerViewController
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    
    picker.dismiss(animated: true, completion: nil)
    
    for (index, result) in results.enumerated() {
        let itemProvider = result.itemProvider
        if itemProvider.canLoadObject(ofClass: UIImage.self)  {
            itemProvider.loadFileRepresentation(forTypeIdentifier: "public.image") { (url, error) in
                // How can you determine the order of the selected images?
            }
        }
    }
}

enter image description here在此处输入图像描述

For example, if the user selects it as in the picture above, the order in which it goes to the results should be the same.例如,如果用户像上图那样选择它,那么它转到结果的顺序应该是相同的。

You can do this pretty readily without an external library.您可以在没有外部库的情况下很容易地做到这一点。

func makeUIViewController(context: Context) -> PHPickerViewController {
        var config = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
        config.filter = .images
        config.selection = .ordered
        config.selectionLimit = 0
        let picker = PHPickerViewController(configuration: config)
        picker.delegate = context.coordinator
        return picker
    }

Using selectionLimit of 0 sets it so that a number is shown when the user taps on a photo.使用selectionLimit0设置它,以便在用户点击照片时显示一个数字。 This number cooresponds to the order in which they tapped.这个数字与他们敲击的顺序相一致。

class Coordinator: NSObject, PHPickerViewControllerDelegate {
    let parent:ImagePicker
    
    init(_ parent:ImagePicker) {
        self.parent = parent
    }
    
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true)
        
        let group = DispatchGroup()
        var images = [UIImage]()
        var order = [String]()
        var asyncDict = [String:UIImage]()
        
        for result in results {
            order.append(result.assetIdentifier ?? "")
            group.enter()
            let provider = result.itemProvider
            if provider.canLoadObject(ofClass: UIImage.self) {
                provider.loadObject(ofClass: UIImage.self) { image, _ in
                    guard let updatedImage = image as? UIImage else {group.leave();return}
                    asyncDict[result.assetIdentifier ?? ""] = updatedImage
                    group.leave()
                }
            }
        }
        group.notify(queue: .main) {
            for id in order {
                images.append(asyncDict[id]!)
            }
            self.parent.images = images
        }
    }
}

Since the process to retrieve the photo is asynchronous, the results can be returned in any order.由于检索照片的过程是异步的,因此可以按任何顺序返回结果。 It does not appear that Apple provides any additional property that carries the user's order selection with it. Apple 似乎没有提供任何附加属性来承载用户的订单选择。 As a result we need to tag the returned images ourselves and then re-assembly them in order into the final array.因此,我们需要自己标记返回的图像,然后按顺序将它们重新组装到最终数组中。

We can make use of the assetIdentifier which is exposed to us if we set our configuration using var config = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared()) Please note that leaving out the photoLibrary parameter will prevent us from getting the assetIdentifier, so make sure to use that instantiation!如果我们使用var config = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())设置配置,我们可以使用暴露给我们的assetIdentifier请注意, photoLibrary参数将阻止我们获取 assetIdentifier,因此请确保使用那个实例化!

We then store each image as it's returned into a dictionary which will have the assetIdentifier as its key.然后,我们将返回的每个图像存储到字典中,该字典将assetIdentifier作为其键。 Just prior to making the async request for the image we will store the assetIdentifier into an array which will give us the intended order that the user selected.在对图像发出异步请求之前,我们会将assetIdentifier存储到一个数组中,该数组将为我们提供用户选择的预期顺序。

Finally, when all async requests are completed, we reassemble the images into the ordered array by getting the ordered keys and accessing our dictionary with those same keys providing the corresponding image.最后,当所有异步请求完成后,我们通过获取有序键并使用提供相应图像的相同键访问我们的字典,将图像重新组合到有序数组中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM