bondgaide
bondgaide

Reputation: 85

Showing UIImageView after finished loading

Currently I have a collection view of thumbnail images, Upon pressing that thumbnail image cell then it should call a function that would retrieve the Image data via API and shows the full image via the hidden ImageView.

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            dataManager.downloadAttachment(id: attachments[indexPath.row].attachmentID)
            if dataManager.dataHolder != nil {
                attachmentImage.image = UIImage.init(data: dataManager.dataHolder!)
                attachmentImage.isHidden = false
            }
            print(attachments[indexPath.row].attachmentID)
        }

and

func downloadAttachment(id:Int) {
    let finalUrl = "\(urlAttachment)\(id)/data"
    if let url = URL(string: finalUrl){
        var request = URLRequest(url: url)
        request.setValue(apiKey, forHTTPHeaderField: header)
        let session = URLSession(configuration: .default)
        let task = session.dataTask(with: request) { (data, response, error) in
            if error != nil {
                print(error!)
                return
            }
            print("Attachment Downloaded")
            self.dataHolder = data
        }
        task.resume()
    }
}

The obvious issue with this is that the image wouldn't show on the first attempt since it would still be retrieving the image and the dataHolder would still be nil, But if I tap on the cell twice then the image will be shown correctly.

Is there a simple way to maybe just tap once and make it shows a place holder until finished downloading and update the place holder with an actual image accordingly? Or any other proper way to handle this?

Upvotes: 1

Views: 163

Answers (1)

Rupesh
Rupesh

Reputation: 141

You can use closures to achieve what you asked for. The updated code looks like this.

func downloadAttachment(id:Int,completionHandler completion: @escaping ((Data)->Void)) {
let finalUrl = "\(urlAttachment)\(id)/data"
if let url = URL(string: finalUrl){
    var request = URLRequest(url: url)
    request.setValue(apiKey, forHTTPHeaderField: header)
    let session = URLSession(configuration: .default)
    let task = session.dataTask(with: request) { (data, response, error) in
        if error != nil {
            print(error!)
            return
        }
        print("Attachment Downloaded")
        self.dataHolder = data
        completion()
    }
    task.resume()
  }
}

Now in collectionViewDidSelectItemAt make this changes

func collectionView (_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
      dataManager.downloadAttachment(id: attachments[indexPath.row].attachmentID,completionHandler: { data in
        if let cell = collectionView.cellForItem(at: indexPath),
                      let data = dataManager.dataHolder,
                      let image = UIImage.init(data: data){
            attachmentImage.image = image
            attachmentImage.isHidden = false
            }
     })
 }

Upvotes: 1

Related Questions