tutchmedia
tutchmedia

Reputation: 139

TableView slows down after scrolling up and down a few times

I have a tableview in xcode that currently downloads from the parse.com backend and displays into the table. It will download a small image and render the image into a circle as well as style each row. Currently it is downloading about 5 rows and outputs lovely but as soon as i scroll up and down a few times the tableview and app becomes slow.

Doing some research i can see suggestions to add the fetching of data on another thread. Currently i am new to all this and i was wondering if any one could assist in showing me how it's done.

My CellForRowAtIndexPath looks like this:

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

tableView.separatorColor = [UIColor colorWithRed:192.0/255.0 green:196.0/255.0 blue:202.0/255.0 alpha:1];

if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
    [self.tableView setSeparatorInset:UIEdgeInsetsZero];
}


if (cell == nil)
{
    cell = [[UITableViewCell alloc]
            initWithStyle:UITableViewCellStyleDefault
            reuseIdentifier:CellIdentifier];
}



PFObject *games = [self.games objectAtIndex:indexPath.row];

//PFFile *imageFile = [games objectForKey:@"gameCover"];


NSString *gameName = [games objectForKey:@"name"];
NSArray *gamePlatforms = [games objectForKey:@"platform"];

NSString *platformsResult = [gamePlatforms componentsJoinedByString:@""];



NSDate *rDate = [games objectForKey:@"release_date"];



// Check to see if the date is set to a Quarter instead
if (rDate == (id)[NSNull null]) {

    self.releaseDate = @"Q1/2014";

} else {

    // Date on the right added to a subview

    //Setup date

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    //uncomment to get the time only
    //[formatter setDateFormat:@"hh:mm a"];
    [formatter setDateFormat:@"dd"];
    //[formatter setDateStyle:NSDateFormatterLongStyle];


    //get the date today


    NSDate *start = [NSDate date];

    NSDateFormatter *f = [[NSDateFormatter alloc] init];
    [f setDateFormat:@"YYYY-MM-dd"];

    NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit
                                                        fromDate:start
                                                          toDate:rDate
                                                         options:0];

    //NSLog(@"%ld", (long)[components day]);

    NSInteger value = [components day];


    NSString *myString = [NSString stringWithFormat:@"%0.0f days", (float)value];


    if ([myString  isEqual: @"1 days"])
    {
        myString = @"1 day";
    }

    self.releaseDate = myString;


}





// Cell Style
// Background Color

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 15, 300.0, 100.0)];
imageView.userInteractionEnabled = NO;
imageView.backgroundColor = [UIColor colorWithRed:209.0/255.0 green:230.0/255.0 blue:244.0/255.0 alpha:1];

// Icon Image



//Game Title Label
UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(80, 25, 200, 20)];
titleLabel.text = gameName;
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13];
titleLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1];

// Game Date Label

UILabel *dateLabel = [[UILabel alloc]initWithFrame:CGRectMake(250, 80, 50, 20)];
dateLabel.text = self.releaseDate;
dateLabel.backgroundColor = [UIColor clearColor];
dateLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13];
dateLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1];
dateLabel.textAlignment = NSTextAlignmentRight;

// Game Platforms

UILabel *platformLabel = [[UILabel alloc]initWithFrame:CGRectMake(250, 25, 50, 20)];
platformLabel.text = platformsResult;
platformLabel.backgroundColor = [UIColor clearColor];
platformLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13];
platformLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1];
platformLabel.textAlignment = NSTextAlignmentRight;

// add the styles to the subview

[cell addSubview:imageView];
//[cell addSubview:iconView];
[cell addSubview:titleLabel];
[cell addSubview:dateLabel];
[cell addSubview:platformLabel];

PFFile *imageFile = [games objectForKey:@"gameCover"];

// If no image

if (imageFile != NULL) {
    NSURL *imageFileUrl = [[NSURL alloc] initWithString:imageFile.url];
    NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl];
    UIImage *myImage = [UIImage imageWithData:imageData];

    UIImageView *iconView = [[UIImageView alloc] initWithImage:myImage];
    iconView.frame = CGRectMake(20.0, 25.0, 50.0, 50.0);

    iconView.layer.masksToBounds = YES;
    iconView.layer.cornerRadius = 25.0f;

    [cell addSubview:iconView];
} else {

    UIImageView *iconView = [[UIImageView alloc]initWithFrame:CGRectMake(20.0, 25.0, 50.0, 50.0)];
    iconView.userInteractionEnabled = NO;
    iconView.image = [UIImage imageNamed:@"img.png"];

    iconView.layer.masksToBounds = YES;
    iconView.layer.cornerRadius = 25.0f;

    [cell addSubview:iconView];
}

return cell;   
}

Sorry for the mess, i can post more code if anyone would like it.

Thanks

Upvotes: 0

Views: 357

Answers (5)

Jignesh Mayani
Jignesh Mayani

Reputation: 7193

User SDWebImageCache

Image is download in background by this class and Image caching in handle by this class, And your table will scroll smooth Follow this link Here:

Upvotes: 0

AntonijoDev
AntonijoDev

Reputation: 1315

Hmmm, U R constantly adding views to UITableViewCell:

[cell addSubview:imageView];
//[cell addSubview:iconView];
[cell addSubview:titleLabel];
[cell addSubview:dateLabel];
[cell addSubview:platformLabel];

U should add them only once in if(cell == nil) block cause they R reusable cells..

Do it like this:

if (cell == nil)
{
    cell = [[UITableViewCell alloc]
            initWithStyle:UITableViewCellStyleDefault
            reuseIdentifier:CellIdentifier];


// Cell Style
// Background Color

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 15, 300.0, 100.0)];

[imageView setTag:100];
imageView.userInteractionEnabled = NO;
imageView.backgroundColor = [UIColor colorWithRed:209.0/255.0 green:230.0/255.0 blue:244.0/255.0 alpha:1];

//Game Title Label
UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(80, 25, 200, 20)];
[titleLabel setTag:101];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13];
titleLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1];

// Game Date Label

UILabel *dateLabel = [[UILabel alloc]initWithFrame:CGRectMake(250, 80, 50, 20)];
[dateLabel setTag:102];
dateLabel.backgroundColor = [UIColor clearColor];
dateLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13];
dateLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1];
dateLabel.textAlignment = NSTextAlignmentRight;

// Game Platforms

UILabel *platformLabel = [[UILabel alloc]initWithFrame:CGRectMake(250, 25, 50, 20)];
[platformLabel setTag:103];
platformLabel.text = platformsResult;
platformLabel.backgroundColor = [UIColor clearColor];
platformLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13];
platformLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1];
platformLabel.textAlignment = NSTextAlignmentRight;

// add the styles to the subview

[cell addSubview:imageView];
//[cell addSubview:iconView];
[cell addSubview:titleLabel];
[cell addSubview:dateLabel];
[cell addSubview:platformLabel];

......
}

UILabel *lbl = [cell viewWithTag:101];
lbl.text = gameName;

lbl = [cell viewWithTag:102];
lbl.text = self.releaseDate;

lbl = [cell viewWithTag:103];
lbl.text = platformsResult;

Do the same thing for your ImageViews, and U will enter the world of reusability and fast tables :)

And also U shouldn't download images like that, U should use some async approach like others recomended

Upvotes: 1

Suhit Patil
Suhit Patil

Reputation: 12023

replace the code in if no image with this
// If no image

if (imageFile != NULL) {
    NSURL *imageFileUrl = [[NSURL alloc] initWithString:imageFile.url];
dispatch_queue_t callerQueue = dispatch_get_current_queue();
dispatch_queue_t downloadQueue = dispatch_queue_create("Image Downloader", NULL);
dispatch_async(downloadQueue, ^{
    NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl];
    dispatch_async(callerQueue, ^{
        UIImage *myImage = [UIImage imageWithData:imageData];

    UIImageView *iconView = [[UIImageView alloc] initWithImage:myImage];
    iconView.frame = CGRectMake(20.0, 25.0, 50.0, 50.0);

    iconView.layer.masksToBounds = YES;
    iconView.layer.cornerRadius = 25.0f;

    [cell addSubview:iconView];
    });
});
}

Upvotes: 0

Jay Gajjar
Jay Gajjar

Reputation: 2741

Use this code to download your image asynchronously in your cellForRowAtIndexPath

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];
                     }
                 });
             }
        });

Upvotes: 0

iSmita
iSmita

Reputation: 1292

Because you are downloading images in cellForRowAtIndexPath. You must have to download images Asynchronously. Because of this performance of application will be increase. So try to download asynchronously.

Upvotes: 1

Related Questions