tags:

views:

286

answers:

1

Hi!

I have created a very simple application where I am trying to insert a custom cell in a table view. However, whenever I return an instance of the Custom Cell, one nothing is displayed on the screen and second, the application enters some kind of weird infinite loop. Any help would be much appreciated. I have attached my code in this question.

-- view controller which is returning custom cells ---

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


  // Try to recover a cell from the table view with the given identifier, this is for performance
  CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCell"];

  // If no cell is available, create a new one using the given identifier
  if (cell == nil) {
  NSArray *topLevelObjects = [[NSBundle mainBundle]
  loadNibNamed:@"sample_1ViewController" owner:self options:nil];
  for (id currentObject in topLevelObjects) 
  {
  if ([currentObject isKindOfClass:[CustomCell class]])
  {
  cell = currentObject;
  break;
  }
  }
  }

  // Fill the cell
 cell.lbl.text = @"test";
 return cell;

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
 return 4;
}

--- custom cell class ---

@interface CustomCell : UITableViewCell {
 IBOutlet UILabel * lbl;
}

@property (nonatomic, retain) IBOutlet UILabel * lbl;

@end

@implementation CustomCell

@synthesize lbl;

@end

----

The custom cell is a UITableCellView resource in the sample_1ViewController.xib file. It contains a UILabel. The identifier for the CustomCell is CustomCell as well.

Please see if you could locate something which might be wrong or tell me of something which I am possibly missing out.

Regards Nitin

+1  A: 

Does sample_1ViewController.nib contain an instance of your viewController class?

Your code appears to re-load that entire nib file every time dequeueResuableCellWithIdentifier: returns nil, and if that nib file contains an instance of the same viewController class, then it will continue to try to reload the nib file indefinitely.

Since all you need to do is return an instance of the cell class, how about this:

First, add a tableCell instance variable to your viewController class:

@class CustomCell;
@interface MyViewController
{
    CustomCell * tableCell;
}
@end

Create the single instance of your cell in your init method:

- (id)initWithNibName:(NSString *)nibNameOrNil
               bundle:(NSBundle *)nibBundleOrNil 
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self == nil) { return nil; }

    tableCell = [[CustomCell alloc] init];

    return self;
}

Be sure to release it in dealloc:

- (void)dealloc
{
    [tableCell release];
}

And now, your delegate method becomes:

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    tableCell.lbl.text = @"test";
    return tableCell;
}
e.James
The main problem with this code is that it assumes that every row will have the same content: "test". I suspect that this was a simplification for posting the question and that in practice a singleton cell will not suffice.
zaph
Thank you so much. Havent tried it, but it makes a lot of sense. So basically, the view associated with controller any other custom views cannot be in the same xib definition. Just out of curiosity, does the viewController replaces the view instance as well in this case.
@zaph: This is actually the way that cells are normally used. The idea is that the same cell gets reused in several (if not all) places within the table. Naturally, something about the cell will have to be changed each time, and I assume that's what the OP intends to do in the delegate method. His original example simply showed adding a "test" label, so I did the same thing in my example to avoid cluttering up the explanation.
e.James
@unknown: I'm not quite sure I understand your question. Usually, you only need to load the xib file once (and quite often this simply happens automagically, via Interface Builder). Every time you load the nib, you will get another copy of the entire set of objects. That's probably what caused your infinite loop; when you loaded the nib the first time, it loaded all of the views, and tried to draw the cells for the tableView, but since your delegate method loads *antoher* copy of the nib file, you get *another* tableView, which again needs to draw its cells, and so on.
e.James