Stop repeating values ​​in UITableViewCell

I have created a UITableViewCell programatically with a custom UITableViewCell class, however for some reason the values are repeating inside the UILabels even though the values being read from the NSMutableArray are correct and that I am clearing these values in the prepareForReuse method of the custom UITableViewCell class.

This is what the cellForRow:AtIndexPath method looks like

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    cellDictionary = [xmlMArray objectAtIndex:indexPath.row];
    static NSString *CellIdentifier = @"Cell";

    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[MatchingCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    // Configure the cell.
    cell.selectionStyle = UITableViewCellSelectionStyleGray;
    cell.itemsDictionary = cellDictionary;
    cellDictionary = nil;
    [cell drawCell];

    return cell;

Then inside then this is what my custom class looks like

#import "MatchingCell.h"
#import "ScreenSize.h"

@implementation MatchingCell

@synthesize itemsDictionary;
@synthesize nameString;
@synthesize addressString;
@synthesize codeString;
@synthesize scrollCell;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
        nameString = [[UILabel alloc] init];
        nameString.backgroundColor = [UIColor clearColor];

        addressString = [[UILabel alloc] init];
        addressString.backgroundColor = [UIColor clearColor];

        codeString = [[UILabel alloc] init];
        codeString.backgroundColor = [UIColor clearColor];

        scrollCell = [[UIScrollView alloc] init];
        scrollCell.backgroundColor = [UIColor whiteColor];

        [scrollCell addSubview:nameString];
        [scrollCell addSubview:addressString];
        [scrollCell addSubview:codeString];
        [self addSubview:scrollCell];
    return self;

- (void)awakeFromNib
    // Initialization code

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state

- (void)drawCell
    nameString.frame = CGRectMake(15.0, 0.5, 70.0, 40.0);
    nameString.text = [itemsDictionary objectForKey:@"Name"];

    addressString.frame = CGRectMake(105.0, 0.5, 95.0, 40.0);
    addressString.text = [itemsDictionary objectForKey:@"Address"];

    codeString.frame = CGRectMake(220.0, 10.5, codeString.frame.size.width, 50.0);
    codeString.text = [NSString stringWithFormat:@"ISN %@: %@",[itemsDictionary objectForKey:@"CodeA"] ,[itemsDictionary objectForKey:@"CodeB"]];
    [codeString sizeToFit];

    scrollCell.frame = CGRectMake(0.0, 0.0, ScreenWidth, 45.0);
    [scrollCell setContentSize:(CGSizeMake((220.0 + codeString.frame.size.width)+15, 45.0))];


- (void)prepareForReuse
    [super prepareForReuse];

    nameString = nil;
    nameString.text = nil;
    addressString = nil;
    addressString.text = nil;
    codeString = nil;
    codeString.text = nil;

    itemsDictionary = nil;

    [self didTransitionToState:UITableViewCellStateDefaultMask];


So my question is how do I stop the values repeating when you scroll new UITableViewCells into view?


Take everything in init, and move it to drawCell:

You clear all of your references in prepare for reuse, but they're never recreated because of this:

if (cell == nil) {
    cell = [[MatchingCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

So your init only runs the first time.

The cell still exists, but none of its references to its subviews do.

Two Notes:

You should remove from subview as well in prepare for reuse, before you nil out the reference. because otherwise you'll keep adding subviews on top of subviews and you'll get bad performance. (as suggested by @user2891327)

You shouldn't be adding views directly to the cell, use its .contentView property for subviews.