views:

33

answers:

4

Hi all,

Im sure this is going to be one of those things where someone points out something really obvious that Im doing but I cant for the life of me find the problem. Basically I have an array of strings and I am loading the text from the array into my uitableviewcells as and when it is needed. The problem comes when I begin to scroll and for some reason cell no.6 ie the 7th cell displays the text from array position 0 over the top of the text from array position 6 and when I scroll back up the text in cell 0 is behind or under (i cant quite tell) the text from array position 6!!?? I have no idea how I am doing this. Here is my code:

    NSMutableArray *titles1 = [[NSMutableArray alloc]initWithCapacity:10];
[titles1 insertObject:[NSString stringWithFormat:@"0"] atIndex:0];
[titles1 insertObject:[NSString stringWithFormat:@"1"] atIndex:1];
[titles1 insertObject:[NSString stringWithFormat:@"2"] atIndex:2];
[titles1 insertObject:[NSString stringWithFormat:@"3"] atIndex:3];
[titles1 insertObject:[NSString stringWithFormat:@"4"] atIndex:4];
[titles1 insertObject:[NSString stringWithFormat:@"5"] atIndex:5];
[titles1 insertObject:[NSString stringWithFormat:@"6"] atIndex:6];
[titles1 insertObject:[NSString stringWithFormat:@"7"] atIndex:7];
[titles1 insertObject:[NSString stringWithFormat:@"8"] atIndex:8];
[titles1 insertObject:[NSString stringWithFormat:@"9"] atIndex:9];

self.secretTitles = titles1;
[titles1 release];

// Customize the appearance of table view cells.

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
        cell.textLabel.adjustsFontSizeToFitWidth = YES;
    }

    // Configure the cell.
    cell.selectedBackgroundView.backgroundColor = [UIColor clearColor];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}


-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {

    secretName = [[UILabel alloc]initWithFrame:(CGRectMake(10, 8, 100, 30))];
    secretName.backgroundColor = [UIColor clearColor];
    secretName.textColor = [UIColor whiteColor];
    secretName.font = [UIFont boldSystemFontOfSize:18];
    secretName.shadowColor = [UIColor colorWithRed:0./255 green:0./255 blue:0./255. alpha:0.7];
    secretName.shadowOffset = CGSizeMake(0, 2.0);
    secretName.text = @"";
    NSLog(@"row = %d", indexPath.row);
    secretName.text = [self.secretTitles objectAtIndex:indexPath.row];
    [cell.contentView addSubview:secretName];
}

Can someone please put me out of my misery. Many thanks

Jules

+1  A: 

You are adding a subview to each cell. The cell object is reused. Since the API doesn't know about your fiddling with the cell, anything you modify to it, beside the standards, is your responsibility.

You should use cell.textLabel or another existing member of UITableViewCell to show your data.

OR: do away with cell reusing alltogether, but that is not a smart thing to do performance-wise.

mvds
+3  A: 

Every time you configure the cell, you add a label as a subview. But the cell might be reused and have been configured before. You should either use the existing labels like textLabel and detailTextLabel or add your label secretName when creating the cell somwhere just after alloc-and-init of a new cell. Then in configureCell you only set the text of the label.

calmh
+2  A: 

You're adding new label to cell's content view each time cell is (re-)used so eventually you get several labels placed on top of each other. The correct approach is to add a label only once and then set text value to it:

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
        cell.textLabel.adjustsFontSizeToFitWidth = YES;

        UILabel *secretName = [[UILabel alloc]initWithFrame:(CGRectMake(10, 8, 100, 30))];
        secretName.backgroundColor = [UIColor clearColor];
        secretName.textColor = [UIColor whiteColor];
        secretName.font = [UIFont boldSystemFontOfSize:18];
        secretName.shadowColor = [UIColor colorWithRed:0./255 green:0./255 blue:0./255. alpha:0.7];
        secretName.shadowOffset = CGSizeMake(0, 2.0);
        secretName.tag = 100; // Arbitrary value that you can use later 
        [cell.contentView addSubview:secretName];
        [secretName release]; // Do not forget to release the label!
    }

    // Configure the cell.
    cell.selectedBackgroundView.backgroundColor = [UIColor clearColor];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    UILabel* label = (UILabel*)[cell.contentView viewWithTag:100];
    label.text = [self.secretTitles objectAtIndex:indexPath.row];

    return cell;
}
Vladimir
Thanks for all the help..... Vladmir's solution has worked for me. I guess I need to read up on re-using cells!!.Many thanks againJules
Jules
+1  A: 

You need to be aware of the way UITableView re-uses cells. What's happening in your code is you're adding secretName to cells that already have it. Here's a quick rewrite of your code:

//we need a way to find the secretName UILabel in the cell's contentView

enum {
    kSecretNameTag = 255
};

(UITableViewCell *)tableView:(UITableView *)tableView 
cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
        // we only need to set up the cell when we create it
        cell.textLabel.adjustsFontSizeToFitWidth = YES;
        cell.selectedBackgroundView.backgroundColor = [UIColor clearColor];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        [self configureCell:cell];
    }
    // grab the secretName UILabel and set the text
    UILabel* secretName = [cell viewWithTag:kSecretNameTag];
    secretName.text = @"";
    NSLog(@"row = %d", indexPath.row);
    secretName.text = [self.secretTitles objectAtIndex:indexPath.row];
    return cell;
}

(void)configureCell:(UITableViewCell *)cell {
    secretName = [[UILabel alloc]initWithFrame:(CGRectMake(10, 8, 100, 30))];
    secretName.backgroundColor = [UIColor clearColor];
    secretName.textColor = [UIColor whiteColor];
    secretName.font = [UIFont boldSystemFontOfSize:18];
    secretName.shadowColor = [UIColor colorWithRed:0./255 green:0./255 blue:0./255. alpha:0.7];
    secretName.shadowOffset = CGSizeMake(0, 2.0);
    secretName.tag = kSecretNameTag;
    [cell.contentView addSubview:secretName];
}
Art Gillespie