Eric Chuang
Eric Chuang

Reputation: 1017

Contents of table view cells change after scrolling

I am using a xib and created a UITableViewController. In my cellForRowAtIndex, I dequeue and set a custom table cell like this:

 CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomTableViewCell" forIndexPath:indexPath];
 cell.delegate = self;

then I set some conditions just to set up the cells. I did something like this:

 if (indexPath.row == 2 || indexPath.row == 5) {
    cell.addressLabel.hidden = YES;
 } else {
     cell.storeHourTitle.text = [[[self.dict objectForKey:@"Hours"] objectAtIndex:indexPath.row] objectAtIndex:0];
     cell.addressLabel.hidden = NO;
 }

just to show more information, my heightForRowAtIndexPath has:

  if (indexPath.row == 2 || indexPath.row == 5) {
        return 280;
  } else {
        return 520;
  }

I've also set:

self.tableView.delegate = self
self.tableView.datasource = self

but I don't think it's necessary? since I'm using a UITableViewController, please verify this for me.

So now when I run my app, the cells load properly, at least the first 5. Once I scroll down, the 5th row's content is incorrect and when I scroll back up, some of the contents change. (e.g. the first cell's content becomes the last cell's (row = 6))

I only return 6 in my numberOfRowsInSection.

Am I not dequeueing the cell properly? From what I've learned, if I use

dequeueReusableCellWithIdentifier forIndexPath

I don't have to do a

if (cell == nil) 

because it will always return something. If you guys spotted any flaw in my UITableView logic, please point it out to me, Thanks!

EDIT:

More detailed code cellForRowAtIndexPath

CustomStoreTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomStoreTableViewCell" forIndexPath:indexPath];

cell.delegate = self;
if (indexPath.row == 2 || indexPath.row == 6) {

    cell.operatingHoursLabel.hidden = YES;
    cell.operatingHoursLabel2.hidden = YES;
    cell.addressLabel.hidden = YES;
    cell.numberLabel.hidden = YES;

    cell.storeHourTitle.text = [[[self.dict objectForKey:@"Hours"] objectAtIndex:indexPath.row] objectAtIndex:0];
    cell.storeHourTitle.textColor = [UIColor blackColor];
    cell.addressTitle.hidden = YES;
    cell.phoneTitle.hidden = YES;
    cell.emailTitle.hidden = YES;
    cell.emailLabel.hidden = YES;

}
else{

    cell.topImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",[[self.dict objectForKey:@"Picture"] objectAtIndex:indexPath.row]]];
    cell.operatingHoursLabel.text = [[[self.dict objectForKey:@"Hours"] objectAtIndex:indexPath.row] objectAtIndex:0];
    cell.operatingHoursLabel2.text = [[[self.dict objectForKey:@"Hours"] objectAtIndex:indexPath.row] objectAtIndex:1];

    cell.addressLabel.text = [[self.dict objectForKey:@"Address"] objectAtIndex:indexPath.row] ;
    cell.addressLabel.numberOfLines = 0;
    cell.numberLabel.text = [[self.dict objectForKey:@"Phone"] objectAtIndex:indexPath.row];
}
return cell;

Upvotes: 0

Views: 3155

Answers (2)

M. Porooshani
M. Porooshani

Reputation: 1837

First things first, if you are using UITableViewController you don't need to set data source and delegate. But if you do, nothing bad happens ;)

If you are seeing weird things after scrolling tableView, there is absolutely something wrong with your cellForRowAtIndexPath: method. In most cases you are setting something conditionally and forgot to set or reset cell for else condition. Or, do you have a custom cell (A cell defined in xib) or have implemented a custom cell controller? In that case use prepareForReuse method to do cleanup work. (I'm guessing you are, because you are setting delegate for cells, meaning there is something going on in your cell)

But for the flaws you have been asking for, I just hope you have defined the delegate property of your cell as weak otherwise you'll get memory leaks.

After posting your cellForRowAtIndexPath it is clear for me now, you are setting some values in your if statement, but forgot to setting them to other values in your else statement. you should always set values symmetrically for your dequeued cells, otherwise they keep their old values set haphazardly in past!

it could be something like this:

CustomStoreTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomStoreTableViewCell" forIndexPath:indexPath];

cell.delegate = self;
if (indexPath.row == 2 || indexPath.row == 6) {

    cell.operatingHoursLabel.hidden = YES;
    cell.operatingHoursLabel2.hidden = YES;
    cell.addressLabel.hidden = YES;
    cell.numberLabel.hidden = YES;

    cell.storeHourTitle.text = [[[self.dict objectForKey:@"Hours"] objectAtIndex:indexPath.row] objectAtIndex:0];
    cell.storeHourTitle.textColor = [UIColor blackColor];
    cell.addressTitle.hidden = YES;
    cell.phoneTitle.hidden = YES;
    cell.emailTitle.hidden = YES;
    cell.emailLabel.hidden = YES;

}
else{
cell.operatingHoursLabel.hidden = NO;
    cell.operatingHoursLabel2.hidden = NO;
    cell.addressLabel.hidden = NO;
    cell.numberLabel.hidden = NO;
    cell.addressTitle.hidden = NO;
    cell.phoneTitle.hidden = NO;
    cell.emailTitle.hidden = NO;
    cell.emailLabel.hidden = NO;
    cell.topImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",[[self.dict objectForKey:@"Picture"] objectAtIndex:indexPath.row]]];
    cell.operatingHoursLabel.text = [[[self.dict objectForKey:@"Hours"] objectAtIndex:indexPath.row] objectAtIndex:0];
    cell.operatingHoursLabel2.text = [[[self.dict objectForKey:@"Hours"] objectAtIndex:indexPath.row] objectAtIndex:1];

    cell.addressLabel.text = [[self.dict objectForKey:@"Address"] objectAtIndex:indexPath.row] ;
    cell.addressLabel.numberOfLines = 0;
    cell.numberLabel.text = [[self.dict objectForKey:@"Phone"] objectAtIndex:indexPath.row];
}
return cell;

Upvotes: 4

Dharmesh Dhorajiya
Dharmesh Dhorajiya

Reputation: 3984

Your code is like this

CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomTableViewCell" forIndexPath:indexPath];
 cell.delegate = self;

Change this code to like this

CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomTableViewCell"];

You set delegate for table not cell.

Upvotes: 1

Related Questions