UITableView Lagging due to Shadows and Borders

I have the following code to add a border colour and drop shadow to the background of my UITableViewCell. My problem is that this code causes a huge lag on the tableView itself.

Please can you tell me how I can optimise my code, preventing the lag of the UITableView?

if ([cell viewWithTag:012] == nil && comment.isReply == NO) {
    UIImageView *iv = [[[UIImageView alloc] initWithFrame:frame] autorelease];
    [iv setImage:[UIImage imageNamed:@"paper"]];
    [iv setTag:012];
    [cell insertSubview:iv atIndex:0];

    [iv.layer setBorderWidth:1.0];
    [iv.layer setBorderColor:[[UIColor whiteColor] CGColor]];

    [iv.layer setShadowColor:[[UIColor blackColor] CGColor]];
    [iv.layer setShadowOffset:CGSizeMake(0, 1)];
    [iv.layer setShadowOpacity:0.75];

}

else if ([cell viewWithTag:012] == nil && comment.isReply == YES) {

    frame.origin.x += 35;

    UIImageView *iv = [[[UIImageView alloc] initWithFrame:frame] autorelease];
    [iv setImage:[UIImage imageNamed:@"paper"]];
    [iv setTag:012];
    [cell insertSubview:iv atIndex:0];

    UIImage *arrow = [UIImage imageNamed:@"arrow"];
    UIImageView *ivs = [[[UIImageView alloc] initWithFrame:CGRectMake(-12, ([cell frame].size.width / 2) + ([arrow size].width/2) , arrow.size.width, arrow.size.height)] autorelease];
    [cell addSubview:ivs];

    [iv.layer setBorderWidth:1.0];
    [iv.layer setBorderColor:[[UIColor whiteColor] CGColor]];

    [iv.layer setShadowColor:[[UIColor blackColor] CGColor]];
    [iv.layer setShadowOffset:CGSizeMake(0, 0)];
    [iv.layer setShadowOpacity:0.75];

}

Answers


You should avoid manipulating the cell on each load, instead you should adjust the UI when the cell is initialized/created.

To illustrate, every time you scroll a new cell (or multiple) could be loaded using the cellForRowAtIndexPath: method, currently you are doing a lot of view changes in this method, but there could be cases where this is not needed (for example the new cell is the same type as the one just scrolled off screen). Move this UI modification to where the cell is initialized not where the data is swapped. You could do this with a subclass or simply like this.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Reuse id
    static NSString *identifier1 = @"identifer-1";
    static NSString *identifier2 = @"identifier-2";
    static NSString *regular = @"regular";

    UITableViewCell *cell;

    if (comment.isReply == NO) {
        cell = [tableView dequeueReusableCellWithIdentifier: identifier1];

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

            // Do the UI modification here
        }
    } else if (comment.isReply == YES) {
        cell = [tableView dequeueReusableCellWithIdentifier: identifier2];

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

            // Do the UI modification here
        }
    } else {
        // Regular cell
        cell = [tableView dequeueReusableCellWithIdentifier: regular];

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

    // Load the data into the cell

    return cell;
}

Hope you get where I'm going with this, the key is to do heavy stuff as little as possible and let the UITableView caching have a greater effect.


In addition to the other optimization advice here, specifying a shadowPath on your CALayer will improve shadow drawing performance. You could determine a path for the shadow with something like this...

iv.layer.shadowPath = [UIBezierPath bezierPathWithRect:iv.bounds].CGPath;

You may also want to look into the shouldRasterize bit on CALayer. This causes the layer to be pre-rendered as a bitmap. Make sure to also provide a rasterizationScale that matches your device if you go this route.

cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

Need Your Help

Python Excel Writer (xlswriter) Insert Image from URL

python excel python-3.x urllib xlsxwriter

How can I insert an image from URL (http) with xlswriter? This is from documentation:

iOS: Draw shadow within UIView

iphone objective-c ios uiview core-graphics

I found some great code that is a subclass of UIView which draws that view with a shadow. Then I can use that view anywhere I want to place the shadow:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.