Reputation: 436
I have a UITableView that uses custom cells, loaded from nibs, and hooked up to a controller (using initWithNibName:bundle:). Basically, I've noticed that dequeueReusableCellWithIdentifier returns a cell that has already been loaded, but when it shouldn't.
Here are my delegate methods:
- (UITableViewCell *) tableView: (UITableView *) tv cellForRowAtIndexPath: (NSIndexPath *) indexPath {
return [[self controllerForTableView: tv cellForRowAtIndexPath: indexPath] cell];
}
- (TableViewCellBaseController *) controllerForTableView: (UITableView *) tv cellForRowAtIndexPath: (NSIndexPath *) indexPath {
[self checkValidTableView: tv];
UIViewController *controller;
Class class;
Event *event;
int row = [indexPath row];
DLOG(@"at index path row: %i", row);
if (row == [currentEvents count]) {
controller = [self tableCellContainerFromNibName: nibName
tableView: tv
atIndex: row
withClass: class];
} else {
class = [EventFeaturedTableViewCell class]; // TODO: OR class = [EventNonFeaturedTableViewCell class];
event = [self findEventFromIndex: row];
lastSelectedEvent = event;
DLOG(@"event: %@", event);
controller = [self tableCellContainerFromNibName: NSStringFromClass(class)
tableView: tv
atIndex: row
withClass: class
perform: @selector(initTableCellWithController:)
on: self];
}
return controller;
}
- (TableViewCellBaseController *) tableCellContainerFromNibName: (NSString *) nibName
tableView: (UITableView *) tableView
atIndex: (int) index
withClass: (Class) class
perform: (SEL) selector
on: obj {
CustomTableViewCell *cell = (CustomTableViewCell *) [tableView dequeueReusableCellWithIdentifier: nibName];
TableViewCellBaseController *controller;
DLOG(@"Cell: %@", cell);
DLOG(@"Cell Identifier: %@", nibName);
if (cell == nil) {
controller = [[class alloc] initWithNibName: nibName bundle: nil];
if (obj) {
[obj performSelector: selector withObject: controller];
}
// run this after setting data as controller.view eager loads the view
cell = controller.cell = controller.view;
cell.controller = controller;
} else {
controller = cell.controller;
if (obj) {
[obj performSelector: selector withObject: controller];
}
}
return controller;
}
- (void) initTableCellWithController: (EventsIndexTableViewCell *) controller {
controller.event = lastSelectedEvent;
}
The Custom Cells have been hooked up in IB to the controller using the controller's view property as well as a 'cell' property. The Custom Cells have a unique identifier set directly in the nib.
I've already verified that the data in the controller is correct.
Here's the effect I'm seeing in the simulator:
http://screencast.com/t/NI2Tpc7GKEi
Notice that the event 'Atlantic Bay' shows up first in the table, then later on in the table. When scrolling back up, it no longer shows up as the first entry in the table!
Upvotes: 0
Views: 3382
Reputation: 299275
To continue viggio24's line, I agree that I don't see a place that you're properly reconfiguring the cell. When you -dequeue... you're going to get a cell that already has "stuff" in it. It's your job to reset everything visible.
You should also read carefully Loading Custom Table-View Cells From Nib Files. Typically you use -loadNibNamed:owner:options:
for this, rather than -initWithNibName:bundle:
.
Upvotes: 2