开发者

UITableview dequeueReusableCellWithIdentifier and scroll-freezing issues

So I have some issues with my tableview. I have a 开发者_如何学运维custom label that I put into a tableview cell to add a little better graphics than the standard UItableviewcell. However, I was running into my first problem,

  1. the text labels that I had on the cells were changing with and over writing each other upon scrolling, only when the cells had moved off screen and then came back. Upon some research I found that maybe it had something to do with dequeueReusableCellWithIdentifier: so I adjusted my code. this is where problem two comes in.

  2. When I load the table everything is in its right place, correct looking and all. However when I start to scroll down I can get to all of my cells except the last one, it will go to the very bottom of the 8th cell and freeze, but I should have 9 cells loaded.

I am quite confused by some of this, could anyone provide some code or guidance to help me along?

Thanks.

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


NSLog(@"Run");
CoCoachAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
static NSString *CellIdentifier = @"Cell";
UILabel *label;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray *keys = [[appDelegate rowersDataStore] allKeys];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    // Configure the cell...


    label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 15, cell.bounds.size.width - 10, 30)] autorelease];
    label.font = [UIFont boldSystemFontOfSize:16];
    label.backgroundColor = [UIColor clearColor];
    label.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.5];
    label.shadowOffset = CGSizeMake(0,1);
    label.textColor = [UIColor colorWithRed:0x4c/255.0 green:0x4e/255.0 blue:0x48/255.0 alpha:1.0];

    switch (indexPath.section) {
        case 0:
            label.frame = CGRectMake(0, 15, cell.bounds.size.width - 10, 30);
            label.textAlignment = UITextAlignmentCenter;
            break;
        case 1:

            label.textAlignment = UITextAlignmentLeft;
            UIImage *accessoryImage = [UIImage imageNamed:@"content_arrow.png"];
            UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessoryImage];
            cell.accessoryView = accessoryView;
            [accessoryView release];
            break;
    }



    UIImageView *imgView = [[UIImageView alloc] initWithFrame:cell.frame];
    UIImage* img = [UIImage imageNamed:@"odd_slice.png"];
    imgView.image = img;
    cell.backgroundView = imgView;
    [imgView release];

    //Selected State
    UIImage *selectionBackground = [UIImage imageNamed:@"row_selected.png"];
    UIImageView *selectionView = [[UIImageView alloc] initWithFrame:cell.frame];
    selectionView.image = selectionBackground;
    cell.selectedBackgroundView = selectionView;
    [selectionView release];
}

switch (indexPath.section) {
    case 0:
        [label setText:@"Click to add new rower"];
        break;
    case 1:
        [label setText:[[[appDelegate rowersDataStore] objectForKey:[keys objectAtIndex:indexPath.row]] objectForKey:@"Name"]];
        break;
}

//Adds Text
[cell addSubview:label];

return cell;

}


I see several issues here. First, the general structure of this method should be...

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

    // Attempt to dequeue the cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // If cell does not exist, create it, otherwise customize existing cell for this row
    if (cell == nil) {
        // Create cell
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        // Configure cell:
        // *** This section should configure the cell to a state independent of 
        //  whatever row or section the cell is in, since it is only executed 
        //  once when the cell is first created.
    }

    // Customize cell:
    // *** This section should customize the cell depending on what row or section 
    //  is passed in indexPath, since this is executed every time this delegate method
    //  is called.

    return cell;
}

Basically, UITableView uses a single UITableViewCell instance to draw every cell in the table view. So, when you first create this cell, you should configure it to a state that is common to all cells that will use this instance, independent of whatever row or section is passed in indexPath. In your example, this involves creating the label, image, and background image instances and adding them as subviews to the cell.

Once the cell is created (aka outside the if (cell == nil) statement), you should customize its properties according to how the cell should look for the specific row and section contained in indexPath. Since you want to access your custom label in this part of the code, I assigned a tag value to it so that we can access it beyond the code segment where it was created using viewWithTag:. Once we have the label, we can customize it according to the section as well as do anything else we want, such as customize the accessory view.

I slightly modified/cleaned up your code below. This is by far not the most efficient or elegant way to do what you want to do, but I was trying to keep as much of your code as possible. I haven't tested this, but if you try it it should work:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Run");
    CoCoachAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    NSArray *keys = [[appDelegate rowersDataStore] allKeys];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        // Configure the cell...

        UILabel *label;
        label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 15, cell.bounds.size.width - 10, 30)] autorelease];
        label.font = [UIFont boldSystemFontOfSize:16];
        label.opaque = NO;
        label.backgroundColor = [UIColor clearColor];
        label.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.5];
        label.shadowOffset = CGSizeMake(0,1);
        label.textColor = [UIColor colorWithRed:0x4c/255.0 green:0x4e/255.0 blue:0x48/255.0 alpha:1.0];
        label.tag = 100;
        [cell addSubview:label];
        [label release];

        UIImageView *imgView = [[UIImageView alloc] initWithFrame:cell.frame];
        UIImage* img = [UIImage imageNamed:@"odd_slice.png"];
        imgView.image = img;
        cell.backgroundView = imgView;
        [imgView release];

        //Selected State
        UIImage *selectionBackground = [UIImage imageNamed:@"row_selected.png"];
        UIImageView *selectionView = [[UIImageView alloc] initWithFrame:cell.frame];
        selectionView.image = selectionBackground;
        cell.selectedBackgroundView = selectionView;
        [selectionView release];
    }

    UILabel *lbl = (UILabel *)[cell viewWithTag:100];
    switch (indexPath.section) {
        case 0:
            cell.accessoryView = nil;

            lbl.frame = CGRectMake(0, 15, cell.bounds.size.width - 10, 30);
            lbl.textAlignment = UITextAlignmentCenter;
            [label setText:@"Click to add new rower"];
            break;
        case 1:
            UIImage *accessoryImage = [UIImage imageNamed:@"content_arrow.png"];
            UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessoryImage];
            cell.accessoryView = accessoryView;
            [accessoryView release];

            lbl.frame = CGRectMake(20, 15, cell.bounds.size.width - 10, 30);
            lbl.textAlignment = UITextAlignmentLeft;
            [lbl setText:[[[appDelegate rowersDataStore] objectForKey:[keys objectAtIndex:indexPath.row]] objectForKey:@"Name"]];
            break;
    }

    return cell;
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜