Anton Tropashko
Anton Tropashko

Reputation: 5816

Dealing with UITableViewCells partially defined in xib partially augmented by code

I have some cells that have some static content defined in Xib and some dynamic content (a table inside a cell) that depends on the datamodel.

So I register Nibs for a synthetic identifier late like so:

 #define LEFTCELLXIB @"P97PromoCardsLeft"
 #define RIGHTCELLXIB @"P97PromoCardsRight"
 #define TOPCELLXIB @"P97PromoCardsTop"
 #define BOTTOMCELLXIB @"P97PromoCardsBottom"

 #define LEFTREUSEPREFIX @"PromoCardImageLeft"
 #define RIGHTREUSEPREFIX @"PromoCardImageRight"
 #define TOPREUSEPREFIX @"PromoCardImageTop"
 #define BOTTOMREUSEPREFIX @"PromoCardImageBottom"

- (NSString *)getCellIdentifier
{
    // cell height varies
    NSString *ident = [NSString stringWithFormat:@"%@ %ld", [self getCellIdentifierPrefix], (long)[self.promotion presentableLinksCount]];
return ident;
}


 - (NSString *)getCellIdentifierPrefix
 {
     NSString *cellIdentifier = TOPREUSEPREFIX;

     switch (self.promotion.imagePos)
     {
         case left:
             cellIdentifier = LEFTREUSEPREFIX;
             break;
         case right:
             cellIdentifier = RIGHTREUSEPREFIX;
             break;
         case top:
             cellIdentifier = TOPREUSEPREFIX;
             break;
         case bottom:
             cellIdentifier = BOTTOMREUSEPREFIX;
             break;
         default:
             break;
     }
     return cellIdentifier;
 }

 - (NSString *)getXibIdentifier
 {
     NSString *xibIndentifier = @"PromoCardImageTop";

     switch (self.promotion.imagePos)
     {
         case left:
             xibIndentifier = LEFTCELLXIB;
             break;
         case right:
             xibIndentifier = RIGHTCELLXIB;
             break;
         case top:
             xibIndentifier = TOPCELLXIB;
             break;
         case bottom:
             xibIndentifier = BOTTOMCELLXIB;
             break;
         default:
             break;
     }
     return xibIndentifier;
 }


 - (id)getCell4:(UITableView*)tableView
 {
     UINib *nib = [UINib nibWithNibName:[self getXibIdentifier] bundle:nil];
     NSString *cid = [self getCellIdentifier];
     [tableView registerNib:nib forCellReuseIdentifier:cid];

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cid];
     NSAssert(cell, @"standard dequeue mechanism must work, fix this");
     return cell;
 }

late. but it does not quite work at runtime:

reason: 'cell reuse indentifier in nib (PromoCardImageTop) does not match the identifier used to register the nib (PromoCardImageTop 1)'

Any ideas how to deal with this?

The fact that there was

added in ios 6 hints that there is some mechanism to accomplish what I'm trying to achieve.

Similar to this question:

Xcode 4.2 "cell reuse indentifier in nib (Cell) does not match the identifier used to register the nib (ThisCell)"

Upvotes: 0

Views: 41

Answers (1)

Anton Tropashko
Anton Tropashko

Reputation: 5816

The solution is rather ugly:

registerClass:forCellReuseIdentifier:

must be used instead of

registerNib: forCellReuseIdentifier:

and then you'd have a rather ugly constructor wasting the object from [super initWithStyle:style reuseIdentifier:reuseIdentifier] and thusly not portable to swift:

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(nullable NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
    NSArray *ugly = [reuseIdentifier componentsSeparatedByString:@" "];
    NSString *cid = ugly[0];
    NSString *xibid = whateverfallbackis;
    if([cid isEqual:LEFTREUSEPREFIX]) {
        xibid = LEFTCELLXIB;
    } else
    if([cid isEqual:RIGHTREUSEPREFIX]) {
        xibid = RIGHTCELLXIB;
    } else
    if([cid isEqual:TOPREUSEPREFIX]) {
        xibid = TOPCELLXIB;
    } else
    if([cid isEqual:BOTTOMREUSEPREFIX]) {
        xibid = BOTTOMCELLXIB;
    } else {
        NSAssert(0, @"implement");
    }
    NSArray *cells = [[NSBundle mainBundle] loadNibNamed:xibid owner:self options:nil];
    return cells.firstObject;
}
return self;
}

Upvotes: 0

Related Questions