Yan
Yan

Reputation: 137

Updating item count after removing an item in CollectionViewController

I am working on an app that displays a set of images using UICollectionView. The user can click on an image, which will segue way to another view controller, and inspect the image. The user can click a delete button to delete the image file, and go back to the presenting CollectionView. The problem is that it appears the item count is not updated and the CollectionView will crash, because the index is now "out of range". I tried to add reloadData() in a couple of places but it did not help. Any idea how to refresh the item count after dismissing the presented ViewController? Seems the viewWillAppear did not get executed upon dismissing and update the item count. The key sections of the codes are below.

class MyCollectionsViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {


override func viewWillAppear(_ animated: Bool) {

    myCollectionView.reloadData()

}


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
    collectionView.reloadData()
    // find out how many image files
    var files = listPhotos(subdir: "myCollections").  // listPhotos is a func to list the image file
    return String(describing: files).components(separatedBy: ",").count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{

    // here to display images
}

   func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    var imagePath = ""

 // find out the path of the image file
        imagePathSelected = String(String(describing: listPhotos(subdir: "myCollections")[indexPath.item]).dropFirst(16))

    }

    // segue to another view controller
        self.performSegue(withIdentifier: "InspectPhotoSegue", sender: imagePathSelected)
    }

}


  class InspectPhotoController: UIViewController {

 @IBAction func deletePhoto(_ sender: Any) {
     // here I delete the image file and then return to the presenting view controller
             self.dismiss(animated: true, completion: nil)
}
}

I also tried the following code, replacing the dismiss with a completion handler to force the reload:

    let presentingVC = self.presentingViewController as! MyCollectionsViewController 
    self.dismiss(animated: true, completion: {presentingVC.viewWillAppear(true)}) 

It worked but only for the first deletion. Afterwards it crashes again due to index out of range error.

Upvotes: 0

Views: 431

Answers (1)

Zain
Zain

Reputation: 153

First of all remove collectionView.reloadData() from numberOfItemsInSection.

Than in your MyCollectionsViewController add this

var selectedImageIndexPath: IndexPath!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard let inspectController = segue.destination as? InspectPhotoController else {return}
    inspectController.itemDeleted = {
    self.listPhotos.remove(at: selectedImageIndexPath.row)
        DispatchQueue.main.async {
            self.collectionView.reloadData()
        }
    }
}

and inside your didSelectItemAt Indexpath method of MyCollectionsViewController add this:

self.selectedImageIndexPath = indexPath

And in your InspectPhotoController add this callback:

var itemDeleted: (()->Void)?

and when deleting image call this callback function like this:

self.itemDeleted?() self.dismiss(animated: true)

Upvotes: 1

Related Questions