开发者

UITableViewCell backgroundView gets reused when it shouldn't

I am wanting to add a custom background and selected background images for my tableview cells. Currently it seems that when the cells get reused, the background images get screwed up, the top cell will use the bottom cells image, etc etc.

Am I reusing cells incorrectly in this case?

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

    static NSString *CellIdentifier = @"Cell";

    UIImageView *linkAvailableImageView = nil;
    UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 44)];
    UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 44)];

    UIImageView *backgroundImage = [[UIImageView alloc] initWithFrame:CGRectMake(10, 0, tableView.bounds.size.width-20, 44)];
    UIImageView *selectedBackgroundImage = [[UIImageView alloc] initWithFrame:CGRectMake(10, 0, tableView.bounds.size.width-20, 44)];


    // Asset
    Asset *asset = nil;
    asset = (Asset *)[items objectAtIndex:indexPath.row];

    int count = [items count];

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

        if (indexPath.row == 0 && count > 1) {
            backgroundImage.frame = CGRectMake(10, 0, tableView.bounds.size.width-20, 45);
            backgroundImage.image = [[UIImage imageNamed:@"MDACCellBackgroundTop.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:10];
            selectedBackgroundImage.frame = CGRectMake(10, -1, tableView.bounds.size.width-20, 45);
            selectedBackgroundImage.image = [[UIImage imageNamed:@"MDACCellBackgroundSelectedTop.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:10];
        } else if (indexPath.row == count-1 && count > 1) {
            backgroundImage.image = [[UIImage imageNamed:@"MDACCellBackgroundBottom.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:10];
            selectedBackgroundImage.image = [[UIImage imageNamed:@"MDACCellBackgroundSelectedBottom.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:10];
        } else if (indexPath.row == 0 && count == 1) {
            backgroundImage.frame = CGRectMake(10, -1, tableView.bounds.size.width-20, 45);
            backgroundImage.image = [[UIImage imageNamed:@"MDACCellBackgroundSingle.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:10];
            selectedBackgroundImage.image = [[UIImage imageNamed:@"MDACCellBackgroundSelectedSingle.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:10];
        } else {
            backgroundImage.image = [[UIImage imageNamed:@"MDACCellBackgroundMiddle.png"] stretchableImageWithLeftCapWidth:1 topCapHeight:10];
            selectedBackgroundImage.image = [[UIImage imageNamed:@"MDACCellBackgroundSelectedMiddle.png"] stretchableIma开发者_如何学PythongeWithLeftCapWidth:1 topCapHeight:10];
        }//end

        backgroundImage.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        [backgroundView addSubview:backgroundImage];
        [backgroundImage release];

        selectedBackgroundImage.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        [selectedBackgroundView addSubview:selectedBackgroundImage];
        [selectedBackgroundImage release];

        cell.backgroundView = backgroundView;
        [backgroundView release];

        cell.selectedBackgroundView = selectedBackgroundView;
        [selectedBackgroundView release];

        linkAvailableImageView = [[[UIImageView alloc] initWithFrame:CGRectMake(cell.contentView.bounds.size.width-39, 9, 24, 24)] autorelease];
        linkAvailableImageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
        linkAvailableImageView.image = [UIImage imageNamed:@"MDACLinkArrow.png"];
        linkAvailableImageView.tag = 3;
        [cell.contentView addSubview:linkAvailableImageView];

    } else {
        linkAvailableImageView = (UIImageView *)[cell.contentView viewWithTag:3];
    }

    // Get asset
    cell.textLabel.opaque = NO;
    cell.textLabel.text = asset.name;
    cell.textLabel.font = [UIFont boldSystemFontOfSize:17];
    cell.textLabel.backgroundColor = [UIColor colorWithWhite:94./255. alpha:1];
    cell.textLabel.textColor = [UIColor whiteColor];
    cell.textLabel.shadowColor = [UIColor colorWithWhite:0 alpha:0.6];
    cell.textLabel.shadowOffset = CGSizeMake(0, -1);

    // Set the kind of disclosure indicator
    if ([asset.children intValue] > 0) {
        //cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }//end

    // Lazy Load the image
    if (!asset.appIcon) {

        // Download icon
        [self startIconDownload:asset forIndexPath:indexPath];

        // if a download is deferred or in progress, return a placeholder image
        cell.imageView.image = [UIImage imageNamed:@"default-icon.png"]; 

    } else {
        cell.imageView.image = asset.appIcon;
    }//end

    return cell;

}//end


The problem here is that you are using the same cell identifier regardless of the position in the table view.

So you initially create the cells based on the indexPath.row and the count, but you associate those cells with an identifier of @"Cell". So when you scroll down dequeueReusableCellWithIdentifier will return a cell configured for the beginning of the list (indexPath.row == 0 && count > 1) and use it for the end of the list.

You need to make sure cell identifier reflects the code at the beginning of your cell==nill if block, so that you only reuse cells that have been configured for the position in the table you are creating.

As Eiko points out, you are also leaking your UIView and UIImageView objects. You could stick them in the if block, release them explicitly or just make them autorelease.


Sorry, but that code has lots of problems: You are leaking the UIView and UIImageView objects, and the whole reuse of cells is wrong, hence your problems.

You should set up a new cell (with views) only in the if (cell == nil) part, and don't forget to release/autorelease your views. Then, outside of that block, you configure your cell accordingly (set its contents).

I strongly suggest to look through some of Apple's example projects!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜