How to deselect a photo after re-opening the photo library?

215 views Asked by At

I'm using PHPicker to handle multiple image selections.

When a user initially selects, for example, 3 images from the photo library, they can re-open the photo library and deselect any of the selected photos. But I'm not sure how to handle the deselect action.

Right now I have this piece of code that handles appending the images to an array, which then I show in the UI.

func makeUIViewController(context: Context) -> some UIViewController {
    
    var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
    configuration.filter = .images // filter only to images
    configuration.selectionLimit = 4 // max 4 selection
    configuration.preselectedAssetIdentifiers = self.imageIdentifierArray
    configuration.selection = .ordered
    //print(self.imageIdentifierArray)
    
    let photoPickerViewController = PHPickerViewController(configuration: configuration)
    photoPickerViewController.delegate = context.coordinator // Use Coordinator for delegation
    
    return photoPickerViewController
}

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true, completion: nil)

    let identifiers = results.compactMap(\.assetIdentifier)
    self.parent.imageIdentifierArray = identifiers

    // Handle selected photos
    for result in results where result.itemProvider.canLoadObject(ofClass: UIImage.self) {
        result.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in
            guard let self = self, let image = image as? UIImage else { return }

            DispatchQueue.main.async {
                selectedPhotos.append(image)
            }
        }
    }
}

I would like to know how I can update the selectedPhotos array whenever a user deselects one of the selected photos from the photo library.

My guess is that the problem is something about result.itemProvider.canLoadObject. Because when I deselect a pre-selected image from the photo library, canLoadObject returns false and it won't enter the for loop again. It enters only when I reselect the photo I deselected.

2

There are 2 answers

0
daredevil1234 On

preselectedAssetIdentifiers has results that don’t include item providers for preselected assets that remain selected.

Therefore, you either need to maintain the asset / image or itemprovider from the previous time you selected it, and use that cached information when you hit a preserved assetIdentifier

2
Om Sanatan On
DispatchQueue.main.async {
    if let index = selectedPhotos.firstIndex(where: { $0.pngData() == image.pngData() }) {
        selectedPhotos.remove(at: index)
    }else {
        selectedPhotos.append(image)
    }
}

just need to find index of selected image and it will be done.