Curnelious
Curnelious

Reputation: 1

Slow scrolling in table view

I have a slow scrolling in my table, the scroller has images that where loaded from web and resized, but the images are already loaded ,so i don't understand why the scrolling is going slow. I have read and tried slow scrolling of UITableView without success(i see empty cells)

This is the cell (it has also sections titles coded )

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{


    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSString *data=@"";
    NSString *icon;

            NSMutableArray *result=[allResults objectAtIndex:indexPath.section];
            NSDictionary *dic=[result objectAtIndex:indexPath.row+1];
            if([[result objectAtIndex:0] isEqualToString:@"types"])
            {
                NSString *title=[dic objectForKey:@"title"];
                icon=[dic objectForKey:@"icon"];
                data=[data stringByAppendingString:[NSString stringWithFormat:@"%@",title]];
            }
            if([[result objectAtIndex:0] isEqualToString:@"subServices"])
            {
                NSString *title=[dic objectForKey:@"title"];
                icon=[dic objectForKey:@"icon"];
                     data=[data stringByAppendingString:[NSString stringWithFormat:@"%@",title]];

            }
            if([[result objectAtIndex:0] isEqualToString:@"businesses"])
            {
                NSString *title=[dic objectForKey:@"title"];
                icon=[dic objectForKey:@"logo"];
                     data=[data stringByAppendingString:[NSString stringWithFormat:@"%@",title]];

            }

    cell.textLabel.numberOfLines = 1;
    cell.textLabel.text = data; 
    cell.textLabel.textColor=[UIColor blackColor];
    cell.textLabel.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:22];
    cell.textLabel.textColor=[UIColor colorWithRed:122.0/255.0 green:181.0/255.0 blue:196.0/255.0 alpha:1];
    cell.imageView.layer.masksToBounds = YES;


    //load image
    NSURL *url = [NSURL URLWithString:icon];
    NSData *imdata = [NSData dataWithContentsOfURL:url];
    UIImage *logo=[UIImage imageWithData:imdata scale:1];

    UIImage *scaled=[self  resizeImage:logo imageSize:CGSizeMake(30, 30)];
    cell.imageView.image=scaled ;
    cell.imageView.layer.masksToBounds = YES;
    cell.imageView.layer.cornerRadius = 12.0;




    return cell;
}

Upvotes: 0

Views: 185

Answers (3)

Dave Wood
Dave Wood

Reputation: 13333

First, what is the icon URL? Is it a file URL to a local image you've already downloaded? If not, you want to download it on a background thread and cache it somewhere local, then use that local file URL here. Note, when the file is downloaded in the background thread, you do not want to reload the whole table! Just upload the one cell (or even better the one imageView) that relates to that image. Otherwise you'll be reloading the table a ridonkulous number of times which will cause other problems.

Next, you're resizing the image on every call. You should resize the image once and cache that result. If you're only using the image in this one location, resize it when you download it and only cache that resized version. If you're using it in another view, cache the original and the resized version.

And, while a small thing, change your three if's to if/else ifs. You're checking the same value, so you don't need to check it three times. Changing the order so the most popular option is checked first will also save you a few comparisons.

Update:

Another thing you can do to make this faster, is configure the cell once. You're setting the font, colours etc, each time. If you move that to the cell's subclass init methods it won't need to call it over and over.

Also, there are a few things you're doing that you don't need to do. Check this updated version with some notes:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString* CellIdentifier = @"Cell";

    UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier
                                                                 forIndexPath:indexPath];


    // Move this part to the init method of a subclass of UITableViewCell
    cell.textLabel.numberOfLines = 1;
    cell.textLabel.textColor = [UIColor blackColor];
    cell.textLabel.font = [UIFont fontWithName:@"Arial Rounded MT Bold"
                                          size:22];
    cell.textLabel.textColor = [UIColor colorWithRed:122.0 / 255.0
                                               green:181.0 / 255.0
                                                blue:196.0 / 255.0
                                               alpha:1];
    cell.imageView.layer.masksToBounds = YES;
    cell.imageView.layer.cornerRadius = 12.0;
    // End of section to move to init methods

    NSString* icon = nil;

    NSMutableArray* result = [allResults objectAtIndex:indexPath.section];
    NSDictionary* dic = [result objectAtIndex:indexPath.row + 1];
    if ([[result objectAtIndex:0] isEqualToString:@"types"]) {
        icon = [dic objectForKey:@"icon"];
    }
    else if ([[result objectAtIndex:0] isEqualToString:@"subServices"]) {
        icon = [dic objectForKey:@"icon"];
    }
    else if ([[result objectAtIndex:0] isEqualToString:@"businesses"]) {
        icon = [dic objectForKey:@"logo"];
    }

    cell.textLabel.text = [dic objectForKey:@"title"];

    // Move the loading of the URL to a background thread if the url is not a local file URL
    //load image
    NSURL* url = [NSURL URLWithString:icon];
    NSData* imdata = [NSData dataWithContentsOfURL:url];
    UIImage* logo = [UIImage imageWithData:imdata
                                     scale:1];

    // Move the resizing of the image to however you load the image from the network,
    // resize it once and cache the results, load the cached version only
    UIImage* scaled = [self resizeImage:logo
                              imageSize:CGSizeMake(30, 30)];
    cell.imageView.image = scaled;

    return cell;
}

Upvotes: 1

sage444
sage444

Reputation: 5684

As show @Andrey Chernukha in his answer you download images synchronously, and this cause slow scrolling.

To avoid this problem you can use AFNetworking that have great category to UIImageView that load images in async mode, or use SDWebImage that have same functionality, or you can write your NSURLSession implementation to load content.

Upvotes: 1

Cocoadelica
Cocoadelica

Reputation: 3026

Don't have the code in the cell to load the image, that's slowing you down. In general, you either pre process the image downloads so they are available instantly in the cell creation method or change the code in the cell to load the images on a background thread so they don't hold up the cell drawing.

Check out the table view programming guide and the block programming guide from apple. Sorry for the brief answer I'm typing on my phone :)

Upvotes: 1

Related Questions