-1

guys, I have UITableView with some images, which are loading from internet. Images is very little, but my tableview isn't work perfect. My code:

static NSString *CellIdentifier = @"Cell";
        TDBadgedCell *cell = [[[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.badgeColor = [UIColor colorWithRed:((float)128 / 255.0f) green:((float)161 / 255.0f) blue:((float)176 / 255.0f) alpha:1];
        NSDictionary *dict = nil;
        if (searching == NO) {
            dict = [companies objectAtIndex:indexPath.row];
        } else {
            dict = [copyListOfItems objectAtIndex:indexPath.row];
        }
        cell.badgeString = [NSString stringWithFormat:@"%@",[dict objectForKey:@"rating"]];
        cell.textLabel.numberOfLines = 2;
        cell.textLabel.text = [dict objectForKey:@"title"];
        cell.textLabel.textColor = [UIColor colorWithRed:((float)80 / 255.0f) green:((float)80 / 255.0f) blue:((float)80 / 255.0f) alpha:1];
        cell.textLabel.font = [UIFont fontWithName:@"Verdana" size:17.0];
        UIImage *img = [[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[dict objectForKey:@"image"]]]] scaleToFitSize:CGSizeMake(16, 16)];
        cell.imageView.image = img;

        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
        return cell;

TDBadgedCell can't be reason, because without images it works perfect. I'm using open sourse classes to resize UIImage. You can found it here.

Have you any ideas?

werbary
  • 1,105
  • 2
  • 14
  • 43
  • Have you tried it with an image from the app's bundle to see whether it is the image or downloading the image? – jrtc27 Feb 01 '12 at 19:51

2 Answers2

2

You could do the image downloading part in another thread so it won't block the main. You can do this like this:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^{
    // download the images here

    dispatch_async(dispatch_get_main_queue(), ^{
     // add them to your cell here

    });
});

So you need to switch to another thread for downloading and then get back to the main thread and add them to the UI. UI elements must only be handled with in the main thread.

Alex Stanciu
  • 5,183
  • 2
  • 24
  • 31
  • I made it, but images are visible only, then I'm touching cell. My code: load: `UIImage *img = [[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[dict objectForKey:@"image"]]]] scaleToFitSize:CGSizeMake(16, 16)];` add to cell: `cell.imageView.image = img; ` – werbary Feb 01 '12 at 20:13
  • 1
    Handling UIImage while not in the main thread could cause unexpected issues. Apple strongly advises not to do that. You could store the image data inside a data structure that's not a UI component. – Alex Stanciu Feb 01 '12 at 20:16
  • I've tried to load NSData firstly, and generate image in main thread, but result is same. – werbary Feb 01 '12 at 20:30
  • you could try doing it like [this](http://stackoverflow.com/a/7565405/97239), it might work better for you... – Alex Stanciu Feb 01 '12 at 21:02
0

I have posted code that shows you to deal with this. We have a class MyImageDownloader that downloads an image on request and posts a notification when it arrives:

https://github.com/mattneub/Programming-iOS-4-Book-Examples/blob/master/p754p772downloader/p754downloader/MyImageDownloader.m

The table view data source supplies a placeholder if a MyImageDownloader has no image, and supplies the image if it has one:

https://github.com/mattneub/Programming-iOS-4-Book-Examples/blob/master/p754p772downloader/p754downloader/RootViewController.m

Thus, all we have to do is reload the table when an image arrives. m.

matt
  • 515,959
  • 87
  • 875
  • 1,141