stefanosn
stefanosn

Reputation: 3324

Function called in uitableview at cellForRowAtIndexPath makes scrolling slow

I have an image that returns everytime the user scrolls the uitableview. This code is inside:

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

The code that is being called is the following and creates a shadow for the image specified:

-(UIImage*)imageWithShadowForImageRight:(UIImage *)initialImage {

    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef shadowContext = CGBitmapContextCreate(NULL, initialImage.size.width + 10, initialImage.size.height + 10, CGImageGetBitsPerComponent(initialImage.CGImage), 0, colourSpace, kCGImageAlphaPremultipliedLast);
    CGColorSpaceRelease(colourSpace);

    CGContextSetShadowWithColor(shadowContext, CGSizeMake(5,-5), 10, [UIColor blackColor].CGColor);
    CGContextDrawImage(shadowContext, CGRectMake(0, 10, initialImage.size.width, initialImage.size.height), initialImage.CGImage);

    CGImageRef shadowedCGImage = CGBitmapContextCreateImage(shadowContext);
    CGContextRelease(shadowContext);

    UIImage * shadowedImage = [UIImage imageWithCGImage:shadowedCGImage];
    CGImageRelease(shadowedCGImage);

    return shadowedImage;
}

The above code makes the scrolling slow and not smooth. Is there a way to overcome this issue by changing the code so it can load the image faster?

Any help appreciated.

Upvotes: 1

Views: 327

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726889

You are right, this is the make-or-break function for smooth scrolling. You need to make it as fast as you can by avoiding as much calculation as possible.

For example, you could add caching for the image processed by your imageWithShadowForImageRight: method: set up an instance of NSCache to store processed images; key them by the index path, and avoid recomputation when the same image is requiested multiple times during the process of scrolling.

-(UIImage*)imageWithShadowForImageRight:(UIImage *)initialImage atIndexPath:(NSIndexPath*) indexPath {
    UIImage *res = [cache objectForKey:indexPath];
    if (!res) {
        // get the shadowed image
        res = shadowedImage;
        [cache setObject:res forKey:indexPath];
    }
    return res;
}

Upvotes: 1

Jeremy Flores
Jeremy Flores

Reputation: 483

Can you use a static shadow image, or does it need to be rendered independently for each image? Dynamic shadows are an expensive operation, especially coupled with scrolling.

Also, can you call this method for all your images in viewDidLoad? That way, you don't have to render the shadows while also devoting computation time to drawing the scroll view and populating the table cells.

Upvotes: 0

Related Questions