Search code examples
iosswiftuicollectionviewuiimagepickercontroller

How to upload image from photolibrary to specific collectionview cell when that cell is selected?


I want to be able to allow users to upload image from photo library to a specific cell in collectionview when it is selected. I have two problems here.

(1) I am not sure if I call the cellTapped() function correctly.

(2) I want to be able to use tag to store indexpath.row but not sure how tag can be called in imagepickercontroller function. Help is appreciated.

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    let cell: UICollectionViewCell = collectionView.cellForItem(at: indexPath)!
    cell.layer.borderWidth = 4.0
    cell.layer.borderColor = UIColor.blue.cgColor
    cellTapped()

}


func cellTapped(){
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = .photoLibrary
    imagePicker.allowsEditing = false
    present(imagePicker, animated: true, completion: nil)
}


func imagePickerControllerDidCancel(_ picker: UIImagePickerController)
{
    dismiss(animated: true, completion: nil)
}


func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

    guard let selectedImage = info[.originalImage] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }
    dismiss(animated: true, completion: nil)
    collectionView?.reloadData()
}

Solution

  • You need to remember which cell you tapped before picking image. You can save the index in collectionView(_:, didSelectItemAt:)

    // instance property
    private var selectedCellIndexPath: IndexPath?
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
        selectedCellIndexPath = indexPath
        let cell: UICollectionViewCell = collectionView.cellForItem(at: indexPath)!
        cell.layer.borderWidth = 4.0
        cell.layer.borderColor = UIColor.blue.cgColor
        cellTapped()
    
    }
    

    Then you need to update you data source when the image is picked and reload collection.

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
        guard let selectedImage = info[.originalImage] as? UIImage else {
            fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
        }
        dismiss(animated: true, completion: nil)
    
        // let us assume that your collection relies on some array called 'images'
        guard let selectedCellIndexPath = selectedCellIndexPath,
              selectedCellIndexPath.item < images.count else {
              return
        }
    
        images[selectedCellIndexPath.item] = images
        collectionView?.reloadData()
    }