Могу ли я установить порядок изображений? PHPickerViewController
Используя PHPickerViewController, в качестве результата будет отображаться результат выбранного изображения. Могу ли я установить порядок изображений?
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?
}
}
}
}
введите описание изображения здесь
Например, если пользователь выбирает его, как на картинке выше, порядок, в котором он переходит к результатам, должен быть таким же.
1 ответ
Вы можете сделать это довольно легко без внешней библиотеки.
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
}
С использованием
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
}
}
}
Поскольку процесс извлечения фотографии является асинхронным, результаты могут быть возвращены в любом порядке. Не похоже, что Apple предоставляет какие-либо дополнительные свойства, которые несут с собой выбор заказа пользователем. В результате нам нужно самим пометить возвращенные изображения, а затем собрать их по порядку в окончательный массив.
Мы можем использовать то, что нам доступно, если мы настроим нашу конфигурацию, используя
Затем мы сохраняем каждое возвращаемое изображение в словарь, ключом которого будет . Непосредственно перед выполнением асинхронного запроса изображения мы сохраним
Наконец, когда все асинхронные запросы выполнены, мы собираем изображения в упорядоченный массив, получая упорядоченные ключи и обращаясь к нашему словарю с теми же ключами, предоставляющими соответствующее изображение.