views:

332

answers:

1

I'm trying to figure out how to implement custom UITableViewCell as nib... I know how UITableView works but implementing custom cell with Interface Builder NIB add to the complexity... but help flexibility.... Si my question is this:

After designing the custom cell in Interface Builder, do we need to create a Obj-C custom class to be assigned as the file owner like we have to do in ViewControlers ?

A: 

You could use a custom class as the file's owner, but you don't have to. I'll show you two techniques to load a table cell from a NIB, one that uses the file's owner, and one that doesn't.

Without using the file's owner, here's a way to load a table cell from a NIB:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *myCell = [tableView dequeueReusableCellWithIdentifier:@"MyID"];
    if (!myCell) {
        NSBundle *bundle = [NSBundle mainBundle];
        NSArray *topLevelObjects = [bundle loadNibNamed:@"MyNib" owner:nil options:nil];
        myCell = [topLevelObjects lastObject];
    }
    /* setup my cell */
    return myCell;
}

The above code is fragile because in the future if you modify the XIB to have more top level objects, this code will probably fail by getting the wrong object from "[topLevelObjects lastObject]". It isn't fragile in any other way though, so this technique is fine to use.

To be a little more explicit, and robust, you can use the file's owner and an outlet instead of using the top level objects. Here's an example of that:

@interface MyTableViewDataSource : NSObject {
    UITableViewCell *loadedCell;
}
@property (retain) UITableViewCell *loadedCell;
@end

@implementation MyTableViewDataSource

@synthesize loadedCell;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *myCell = [tableView dequeueReusableCellWithIdentifier:@"MyID"];
    if (!myCell) {
        [[NSBundle mainBundle] loadNibNamed:@"MyNib" owner:self options:nil];
        myCell = [[[self loadedCell] retain] autorelease];
        [self setLoadedCell:nil];
    }
    /* setup my cell */
    return myCell;
}
@end
Jon Hess
I'm using the first method as it seems to be used by a lot of dev... But, I prefer the second because it eventually gives me more control of what we can do in the custom class to put more init code.... more object oriented...
JFMartin

related questions