0

Now I have a custom cell with the image and label. Later I print these cells by:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell:customCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! customCell

    var url = NSURL(string: postCover[indexPath.row])

    if let data = NSData(contentsOfURL: url!) { 
        cell.cellImage.image = UIImage(data: data)
    }

    var title = postTitle[indexPath.row]

    cell.cellLabel.text = title

    let indexPath = tableView.indexPathForSelectedRow()

    return cell
}

and when I open an app and scroll it freezes. How can I fix this bug?

I read about it, that I must use async image loading in my tableView, but don't I load them async already?

I searched and think about it 4-5 days and nothing. Can anyone give me some tips, please?

Orkhan Alizade
  • 7,379
  • 14
  • 40
  • 79
  • 1
    use third party api AFNetworking https://github.com/AFNetworking/AFNetworking – Mukesh May 22 '15 at 05:54
  • @DharmeshKheni what this line means - `et currentImage = deals[indexPath.row].imageID`? it prints the next error: `could'n find member imageID` – Orkhan Alizade May 22 '15 at 06:04
  • @muku I did install AFNetworking to my project. What I must to do for now? Can you help me? – Orkhan Alizade May 22 '15 at 06:32
  • Duplicates http://stackoverflow.com/questions/16663618/async-image-loading-from-url-inside-a-uitableview-cell-image-changes-to-wrong/32601838#32601838 – kean Oct 05 '15 at 14:14

3 Answers3

2

You can schedule the downloading of image asynchronously for each cell using GCD as-

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell:customCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! customCell

    var url = NSURL(string: postCover[indexPath.row])

cell.imageView.image = nil;
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
        dispatch_async(queue, ^(void) {

            NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:parsedData[@"imageLR"]];

            UIImage* image = [[UIImage alloc] initWithData:imageData];
            if (image) {
                 dispatch_async(dispatch_get_main_queue(), ^{
                     if (cell.tag == indexPath.row) {
                         cell.imageView.image = image;
                         [cell setNeedsLayout];
                     }
                 });
             }
        });

return cell
}

for Swift you can do so as

if let data = self.cache.objectForKey(urlString) as? NSData {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
            let image = UIImage(data: data)
            dispatch_async(dispatch_get_main_queue()) {
                cell.imageView.image = image;
            }
        }
Sanjay Mohnani
  • 5,947
  • 30
  • 46
  • 1
    Great, but could you please translate it to Swift? – saurabh May 22 '15 at 05:58
  • 1
    @OrkhanAlizade, sure I'll do that – Sanjay Mohnani May 22 '15 at 06:00
  • 2
    This will not cache image and as user scroll the data will download again ... use SDWebImage , that will do both downloading and caching – MOHAMMAD ISHAQ May 22 '15 at 06:04
  • The problem the approach is there is no caching, so the cell image loads every time when the table is scrolled. Use a cache policy or SDWebimageCache library to solve this. – nprd May 22 '15 at 06:15
  • 1
    for table view's with few cells you can use above approach, also for downloading image only once you can save the downloaded image in dictionary for url as key, and if you need caching than as suggested by all, use SDWebImage – Sanjay Mohnani May 22 '15 at 06:18
2

You can use third part Library SDWebImage on gitHub . It`s base on Objective-C, and there is another Library Kingfisher which base on Swift. And maybe this is what you want.

BourneWeng
  • 21
  • 6
  • 2
    KingFisher is really simple and straigthforward. But I have one question, what is the cleanest way to refresh your cell after kingfisher finish the download? Do you have to set a callback and call .reloadRowsAtIndexPath? –  Oct 13 '15 at 12:35
-1

create a bridging header in swift.Import AFNetworking header files

and then find these method setImageWithURLRequest

cell.imageView.setImageWithURLRequest you can call in these way

Mukesh
  • 3,680
  • 1
  • 15
  • 32