iosswiftuitableviewuiimage

UITableView cell images keep on switching cells when scrolling


I have an array of objects (which includes the data necessary to download photos from Google Places API) and when I try to load the elements of those objects in the tableView cells, the images as well as the titleLabels keep on being switched around while scrolling.

Here is my tableView function for cellForRowAtIndexPath

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("TestTableViewCell", forIndexPath: indexPath) as! TestTableViewCell

    let business = businessObjects[indexPath.row]

    if businessShown[indexPath.row] == false{
        self.getImageFromPhotoReference(business.businessPhotoReference) { (photo, error) -> Void in
            cell.backgroundImage.image = photo
        }
    }
    cell.businessNameLabel.text = business.businessName

    businessShown[indexPath.row] = true
    return cell
}


 func getImageFromPhotoReference(photoReference: String, completion: (photo: UIImage, error: NSError?) -> Void){
    let photoRequestParams = ["key":"##", "photoreference": photoReference, "maxheight": "800"]

    let placePhotoURLString = self.googleClient.buildPlacePhotoURLString(photoRequestParams)
    let photoRequestURL = NSURL(string: placePhotoURLString)!

    self.getDataFromUrl(photoRequestURL) { (data, response, error) -> Void in
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            guard let data = NSData(contentsOfURL: photoRequestURL) where error == nil else { return }
            let imageFile = UIImage(data: data)!

            completion(photo: imageFile, error: error)
        })
    }
}

private func getDataFromUrl(url: NSURL, completion: ((data: NSData?, response: NSURLResponse?, error: NSError? ) -> Void)) {
    NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
        completion(data: data, response: response, error: error)
        }.resume()
}

Thank you


Solution

  • The issue is the asynchronous network call completes when a reused cell has already loaded new data on top of it. My suggestion is to use a image caching utility like Kingfisher or HanekeSwift as they auto cancel async calls on cell reuse and also cache the images so there's less network calls.