Zack
Zack

Reputation: 871

Last TableView Cell Not working

I will try to explain this as best as I can and hope someone can understand what's going on:

I am using core data to load data into a UITableView. I am trying to add a "last cell" to the end of the TableView to display a logo. Here is my code:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  numberOfRows = section;
return     [[[self.fetchedResultsController sections] objectAtIndex:numberOfRows] numberOfObjects]+1;

}



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

cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[ReminderCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"cellBackground.png"]];

row = indexPath.row;


if (row == [[[self.fetchedResultsController sections] objectAtIndex:numberOfRows] numberOfObjects]) {
    NSLog(@"%u",[[[self.fetchedResultsController sections] objectAtIndex:numberOfRows] numberOfObjects]);
    cell.productLabel.text = nil;
    cell.companyLabel.text = nil;
    cell.dateLabel.text = nil;
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.logo.hidden = NO;
    cell.renewLabel = nil;


}

else {

    Reminder *reminder = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.productLabel.text = reminder.product;
    cell.companyLabel.text = reminder.company;
    cell.dateLabel.text = reminder.date;
    cell.logo.hidden = YES;

}

return cell;

}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    row = [indexPath row];

if (row == [[[self.fetchedResultsController sections] objectAtIndex:numberOfRows] numberOfObjects]) {
    return 50;
}

return 78;

}

As you can tell I am telling the last cell to not have an accessory type while all of the other cells are going to have one.

The Normal Cell w/ Accessory Arrow: Has Accessory Arrow

Last cell: Last Cell

Everything works beautifully until I scroll down to the bottom where the last cell is and then scroll back up. The accessory arrow disappears in some of the table cells that are supposed to have it!! (BUT not all of them)

Same Cell but Arrow has disappeared: Has No Arrow

What is going on here?

Upvotes: 0

Views: 749

Answers (4)

Mat
Mat

Reputation: 7633

You can try to customize your cell just after it is displayed by using the below callback of UITableViewDelegate:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row != (yourDataSource.count-1) {
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }else{
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
}

Upvotes: 0

Tobi
Tobi

Reputation: 5519

That's because of the queueing mechanism. The tableView dequeues an arbitrary cell from it's cache. If that cells happens to be one of those on which you previously set:

cell.accessoryType = UITableViewCellAccessoryNone;

it won't have an accessory indicator. The easiest way to fix that (in my opinion, of course you can also use diffent reuse identifier) is the modify your code like this:

else {

    Reminder *reminder = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.productLabel.text = reminder.product;
    cell.companyLabel.text = reminder.company;
    cell.dateLabel.text = reminder.date;
    cell.logo.hidden = YES;

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

}

Upvotes: 2

edzio27
edzio27

Reputation: 4140

I would do this in this way that define two CellIdentifier, one for normal cell and one for last cell:

static NSString *CellIdentifier = @"Cell";
static NSString *CellIdentifierBottom = @"CellBottom";

Create yout cell i if contruction:

if (row != lastTableViewIndex) {
    //create cell with CellIdentifier
} else {
    //create cell with CellIdentifierBottom
}

Upvotes: 1

amarkon
amarkon

Reputation: 439

The problem is the call of dequeReusableCellWithIdentifier:, because all of your cells have the same identifier. This means that when the "last cell" appears and then scrolls off, it is the next in cue for the reusable cell, and because all of your cells have the same identifier, every time one of these falls off of the screen, the next one on will have no accessory. You need to come up with an implementation that gives a different identifier to the "last cell."

Upvotes: 1

Related Questions