1

As I scroll up and down the table view the data in each cell becomes duplicated and unreadable. Does anyone have any suggestions for the below?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString *CellIdentifier = @"Cell";
     NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
     [dateFormat setDateStyle:NSDateFormatterShortStyle];

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

     UILabel *label1 = [[UILabel alloc]initWithFrame:CGRectMake(10, 12, 250, 20)];
     UILabel *label2 = [[UILabel alloc]initWithFrame:CGRectMake(250, 12, 50, 20)];
     label1.tag= 666;
     label2.tag= 666;
     [cell.contentView addSubview:label1];
     [cell.contentView addSubview:label2];

     // Configure the cell...
     President *p = (President *)[self.importedRows objectAtIndex:indexPath.row];
     label1.text = p.no;
     label2.text = p.name;

     UILabel* cellLabel = (UILabel*)[cell viewWithTag: 666];
     cellLabel.text = [NSString stringWithFormat:p.no , p.name];


     return cell;
}
Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
shennis90
  • 23
  • 6

6 Answers6

3

dequeueReusableCellWithIdentifier caches the generated cells. So if you request a cell which you already created before this cell will NOT be generated again from scratch (meaning that the labels you added before already exists!).

So when adding the labels tag them with a unique number :

label1.tag= 666;
label2.tag= 667;

And before adding them to the cell remove them as follows :

UIView *labelView = [cell.contentView viewForTag:666];
if (labelView != nil) {
    [labelView removeFromSuperView];
}

And do the same with the second label.

giorashc
  • 13,691
  • 3
  • 35
  • 71
  • @flexaddicted if created in storyboard dequeueReusableCellWithIdentifier will not return nil unless there is no nib or class defined for that cell. If not then you are right about the performance issue – giorashc Jan 14 '14 at 12:24
0

because you are adding label1 and label2 again and again to cell.

UILabel *label1 = [[UILabel alloc]initWithFrame:CGRectMake(10, 12, 250, 20)];
UILabel *label2 = [[UILabel alloc]initWithFrame:CGRectMake(250, 12, 50, 20)];
[cell.contentView addSubview:label1];
[cell.contentView addSubview:label2];

As the cell is reused, same cell is used for another row, and it already has label1,2. but you are creating label1,2 again and again and adding them to it.

Give different tags for label1,label2.Check if viewWithTag:666 and 667 is present.If not present add them as subview ,if already present, just get them using viewWithTag and change their text values.

santhu
  • 4,796
  • 1
  • 21
  • 29
0

The problem here is with below code:

UILabel* cellLabel = (UILabel*)[cell viewWithTag: 666];
     cellLabel.text = [NSString stringWithFormat:p.no , p.name];

I have tried your code, commenting these two lines stop overlapping. You can try to change the frame of this label.

Ashutosh
  • 2,215
  • 14
  • 27
0

I suggest making your own subclass of UITableViewCell which has two UILabel's on it, then in the method you're using above, create instances of your subclass rather than UITableViewCell if the cell doesn't exist, then populate the labels.

In your custom cell implementation file, you'll have to override the 'prepareForReuse' method, and in it set the text of your labels to nil (@""). This properly uses the 'dequeueWithReuseIdentifier' functionality and only creates the labels when necessary, rather than only showing them when required.

Matthew Hallatt
  • 1,310
  • 12
  • 24
0

A solution where you can gain performance is the following.

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

    // create and add labels to the contentView
}

// retrieve and update the labels

Obviously you could also create your UITableViewCell subclass.

Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
0

You could also try this swag (fresh answer, get your fresh answer!):

BOOL doesContain = [cell.subviews containsObject:imageView]; 
if (!doesContain)
{
     [cell.contentView addSubview:imageView];
}
imageView.image = yourImage];

Also for a quick way to subclass all of your stuff, check my answer.

Community
  • 1
  • 1
Michael Lorenzo
  • 628
  • 10
  • 20