I am able to design custom UITableViewCells and load them just fine using the technique described in the thread found at http://forums.macrumors.com/showthread.php?t=545061.
Look at the answer I gave to this question:
Is it possible to design NSCell subclasses in Interface Builder?
It's not only possible to design a UITableViewCell in IB, it's desirable because otherwise all of the manual wiring and placement of multiple elements is very tedious. Performaance is fine as long as you are careful to make all elements opaque when possible. The reuseID is set in IB for the properties of the UITableViewCell, then you use the matching reuse ID in code when attempting to dequeue.
I also heard from some of the presenters at WWDC last year that you shouldn't make table view cells in IB, but it's a load of bunk.
Louis method worked for me. This is the code I use to create the UITableViewCell from the nib:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"];
if (cell == nil)
{
UIViewController *c = [[UIViewController alloc] initWithNibName:@"CustomCell" bundle:nil];
cell = (PostCell *)c.view;
[c release];
}
return cell;
}
I create my custom view cells in a similar manner - except I connect the cell through an IBOutlet.
The [nib objectAt...]
approach is susceptible to changes to positions of items in the array.
The UIViewController
approach is good - just tried it, and it works nice enough.
BUT...
In all cases the initWithStyle
constructor is NOT called, so no default initialisation is done.
I have read various places about using initWithCoder
or awakeFromNib
, but no conclusive evidence that either of these is the right way.
Apart from explicitly calling some initialization method in the cellForRowAtIndexPath
method I haven't found an answer to this yet.
I can't remember where I found this code originally, but it's been working great for me so far.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"CustomTableCell";
static NSString *CellNib = @"CustomTableCellView";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (UITableViewCell *)[nib objectAtIndex:0];
}
// perform additional custom work...
return cell;
}
Example Interface Builder setup...
A while back I found a great blog post on this topic at blog.atebits.com, and have since started using Loren Brichter ABTableViewCell class to do all of my UITableViewCells.
You end up with a simple container UIView to put all of your widgets, and scrolling is lightning fast.
Hope this is useful.
I followed Apple's instructions as linked by Ben Mosher (thanks!) but found that Apple omitted an important point. The object they design in IB is just a UITableViewCell, as is the variable they load from it. But if you actually set it up as a custom subclass of UITableViewCell, and write the code files for the subclass, you can write IBOutlet declarations and IBAction methods in the code and wire them up to your custom elements in IB. Then there is no need to use view tags to access these elements and you can create any kind of crazy cell you want. It's Cocoa Touch heaven.