0

I am working on a simple app which has the following premise:

  • TableViewController with a plus button - the user presses and is presented modally with text fields to enter to represent the name, title, etc. When they press save, the view controller disappears and adds those entries to the Core Data database and the entries are displayed in the table View.

I had this working very well with standard cells like subtitle, etc. I am using NSFetchedResultsController and I want to now deploy custom cells.

I changed the style to be a custom cell in the Storyboard and added three labels which would represent the name, title and amount (added by the user).

I created a custom class for the UITableViewCell and ensured that this table view cell was that custom reference class. I added the properties for the labels: nameLabel, amountLabel, titleLabel.

I imported this class into the full TableViewController class. Following tutorials online, it states to essentially just use the cellForRowAtIndexPath method with something like this:

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

  TableCell *tablecell = (TableCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];


  NSDictionary * dict = [self.tweetsArray objectAtIndex:indexPath.row];

  tablecell.title.text = [dict objectForKey:@"tweet"];

  UIImage *imageIcon = [UIImage imageNamed:[dict objectForKey:@"image"]];
  [tablecell.cellImage setImage:imageIcon];

  return tablecell;

}

That is not my code but referenced from: http://www.codigator.com/tutorials/ios-uitableview-tutorial-custom-cell-and-delegates/ but the concept is the same.

Because I am using NSFetchedResultsController, I actually have two methods for the cell:

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    Transaction *transaction = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.nameLabel.text =[NSString stringWithFormat:@"%@", transaction.name];
    cell.amountLabel.text = [NSString stringWithFormat:@"%@", transaction.amount];
    cell.eventLabel.text = [NSString stringWithFormat:@"%@", transaction.title];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"People";

    TransactionCell *cell = (TransactionCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Set up the cell...
    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

This code does not work because the nameLabel, amountLabel is not actually recognised.

I have (like the code at the top) put all of the information into the cellForRowAtIndexPath, but then I get an error from the

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { 

method because it has the following entry:

case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

I have tried changing the method signature of the

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {

to be:

- (void)configureCell:(TransactionCell *)cell atIndexPath:(NSIndexPath *)indexPath {

but that just does not seem right to me and there are warnings.

So basically I'm not trying to achieve anything complicated. I am simply trying to create a custom cell with three labels - why is the "cell" from the cellForRowAtIndexPath not being recognised in the configureCell method?

Finally, the custom cell has a specific size, bigger than normal and that does not appear when the app is run; it remains normal. I did this in the inspector of the cell but also added the following code to the end of the table view class:

- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView
{
    tableView.rowHeight = 80;
}

But it remained the normal height.

Any assistance on this would be massively appreciated!

Thanks,

amitsbajaj
  • 1,304
  • 1
  • 24
  • 59

2 Answers2

1

You have two options:

  • Change the signature of configureCell to

    - (void)configureCell:(TransactionCell *)cell atIndexPath:(NSIndexPath *)indexPath
    

    and add an additional cast in

    case NSFetchedResultsChangeUpdate:
        [self configureCell:(TransactionCell *)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
        break;
    
  • Or leave the signature of configureCell as it is and cast inside the method:

    - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
        TransactionCell *tcell = (TransactionCell *)cell;
        Transaction *transaction = [self.fetchedResultsController objectAtIndexPath:indexPath];
        tcell.nameLabel.text = transaction.name;
        tcell.amountLabel.text = transaction.amount;
        tcell.eventLabel.text = transaction.title;
    }
    

    (Note that all the stringWithFormat: calls are unnecessary.)

I would use the second method, but that is just a matter of taste.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Thanks Marin (once again). The second method worked like a treat. I wasn't a fan of changing the method signature (because I just don't know what kind of effect it would have, etc), but the second method worked brilliantly. Thanks so much for that. Any idea on the size of the cell? I have set it in the inspector and even added that method, but it always defaults to the original size of the cell and I'm not entirely sure why! – amitsbajaj Nov 12 '13 at 09:25
  • @amitsbajaj: You are welcome. - Do you have a search display controller? Otherwise you could just set `tableView.rowHeight = 80;` in `viewDidLoad`. If that does not help then perhaps start a new question, because it is a separate problem. – Martin R Nov 12 '13 at 09:31
  • Thanks Martin - that is the key here and it's working. It's displaying slightly strangely but I will raise another question for that. Once again, I'm progressing my learning (and my app) with your assistance, so I'm grateful! – amitsbajaj Nov 12 '13 at 09:39
1

This is because you probably forgot to call

self.tableView registerClass:forCellReuseIdentifier:

Or

self.tableView registerNib:forCellReuseIdentifier:

in your viewDidLoad (assuming self.tableView point to your UITableView)

by the way do not implement both! If you made a xib for your cell, use registerNib alone. If you created a UITableViewCell subclass, use registerClass alone.

Nicolas Manzini
  • 8,379
  • 6
  • 63
  • 81
  • Just note that *if* the cell is defined as "prototype cell" in the storyboard then you don't have to register it at all (and you shouldn't). – Martin R Nov 12 '13 at 08:51
  • okay I didn't know that.but xibs can be erratic sometimes, it worth trying. – Nicolas Manzini Nov 12 '13 at 09:01
  • Thanks Nicolas and Martin - this did make sense but I felt more comfortable with using Martin's response below which worked for me. Thanks so much for the suggestion here though - massively appreciated! – amitsbajaj Nov 12 '13 at 09:26