Parv Bhasker
Parv Bhasker

Reputation: 1901

Same Cells repeat after Scrolling

I am using table view using custom coding with tag method to save memory.

I was successful to show data in the view but the problem is if 10 cells are showing and then if I scroll down like for one cell then it should show 2-11 cell data but it switches to 1-10 again.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cellID";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    UILabel *cellNAMElabl = nil;
    UILabel *cellDetaillabl = nil;
    UIImageView *imgView = nil;

    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];

        cellNAMElabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 10, 150, 20)];
        [cellNAMElabl setTag:1];
        cellNAMElabl.text = [name5 objectAtIndex:indexPath.row];
        UIFont *myFont1 = [ UIFont fontWithName: @"Arial" size: 20.0 ];
        cellNAMElabl.font  = myFont1;
        [cell.contentView addSubview:cellNAMElabl];

        cellDetaillabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 28, 150, 20)];
        [cellDetaillabl setTag:2];
        cellDetaillabl.text = [email5 objectAtIndex:indexPath.row];
        UIFont *myFont = [ UIFont fontWithName: @"Arial" size: 13.0 ];
        cellDetaillabl.font  = myFont;
        [cell.contentView addSubview:cellDetaillabl];

        imgView=[[UIImageView alloc] initWithFrame:CGRectMake(25, 5, 52, 50)];
        [imgView setTag:3];

        imgView.image = [imagepath5 objectAtIndex:indexPath.row];
        [cell.contentView addSubview:imgView];
    }

    cellNAMElabl = (UILabel *)[cell viewWithTag:1];
    cellDetaillabl = (UILabel*)[cell viewWithTag:2];
    imgView = (UIImageView*)[cell viewWithTag:3];

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

Upvotes: 1

Views: 654

Answers (4)

gnasher729
gnasher729

Reputation: 52538

The way this dequeueReusableCellWithIdentifier works: If iOS detects that a cell is not displayed anymore, then dequeueReusableCellWithIdentifier will return that cell. If there is no unused cell, it returns nil. So what you need to do:

If dequeueReusableCellWithIdentifier returns nil, then you create a new cell, and you do all the setup that is required for all cells with the same identifier. For example, add view tags like you did, set fonts, colors etc.

Then, whether you use a cell returned by dequeueReusableCellWithIdentifier or one that you just created yourself, you add all the information that is used for the specific section/row that you want to display. So if row 1, row2, and so on display different text, then you set the text here. That's what you didn't do, so when a cell was reused, you didn't set the new text for it.

So the idea is that all the work that is the same for all rows is only done once when a cell is created, and only as many cells are created as is needed to display them on the screen. The work that is different from row to row is done for each row, as it is needed.

Upvotes: 1

0yeoj
0yeoj

Reputation: 4550

What you want to do is..

add/setup the tableViewCell UI if the cell is nil..

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cellID";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];

        UILabel *cellNAMElabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 10, 150, 20)];
        cellNAMElabl.tag = 1;
        cellNAMElabl.font  = [UIFont fontWithName: @"Arial" size: 20.0 ];
        [cell.contentView addSubview:cellNAMElabl];

        UILabel *cellDetaillabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 28, 150, 20)];
        cellDetaillabl.tag = 2;
        cellDetaillabl.font  = [UIFont fontWithName: @"Arial" size: 13.0 ];
        [cell.contentView addSubview:cellDetaillabl];

        UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(25, 5, 52, 50)];
        imgView.tag = 3;
        [cell.contentView addSubview:imgView];
    }

//and just update your data if the cell is currently exist and not nil..
//you already called the view using tag so, you dont need those:
//    UILabel *cellNAMElabl = nil;
//    UILabel *cellDetaillabl = nil;
//    UIImageView *imgView = nil;

    ((UILabel *)[cell viewWithTag:1]).text = [name5 objectAtIndex:indexPath.row]; // cellNAMElabl
    ((UILabel*)[cell viewWithTag:2]).text = [email5 objectAtIndex:indexPath.row]; // cellDetaillabl
    ((UIImageView*)[cell viewWithTag:3]).image = [imagepath5 objectAtIndex:indexPath.row]; // imgView

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

hope this have help you, happy coding cheers!

Upvotes: 0

some_id
some_id

Reputation: 29886

If you set a breakpoint in the if cell == nil block its probably only being hit for the first set if your reuseID is correct. Thats why its never getting a chance to set any new data into the cell.

You should not look for a nil cell, rather use a correct reuseID and a prototype cell in IB that is set to a custom UITableViewCell subclass you create.

Its also good practice to implement prepareForReuse on custom cells, where you clear any cell data e.g. label.text = nil, imageview.image = nil

This way you dont get invalid data from previously dequeued cells. It might not solve the question directly, but it would have wiped the fixed data set in your if cell == nil block to help debug.

Upvotes: 0

NightFury
NightFury

Reputation: 13546

You are not assigning new content to subviews, if they have been already created. After the case if(cell == nil), these you have just got references.

cellNAMElabl = (UILabel *)[cell viewWithTag:1];
cellDetaillabl = (UILabel*)[cell viewWithTag:2];
imgView = (UIImageView*)[cell viewWithTag:3];

Here when cell is not nil, you are just getting references to labels and imageview, but you are not setting new text and image from data source. Add following lines and remove them from the if (cell == nil) part:

cellNAMElabl.text = [name5 objectAtIndex:indexPath.row];
cellDetaillabl.text = [email5 objectAtIndex:indexPath.row];
imgView.image = [imagepath5 objectAtIndex:indexPath.row];
                     [cell.contentView addSubview:imgView]; 

Upvotes: 1

Related Questions