开发者

Read property from XIB file prior to instantiation

There are a couple of times I've wanted to use the value from a XIB file prior to creating an instance of the class; the two that come to mind are:

  • Calculating height for table cells - all cells in a table are based on the XIB's height, each cell might be extended, if more information is shown, but the "base" height should come from the XIB.
  • UIFont and sizes - there isn't much point in duplicating these values as constants, but they are often useful for calculating cell height.

In both cases, the cell height needs to be calculated for HeightForCell, prior to instantiating XIB instances.

The two approaches I've considered are:

  • instantiation a garbage instance of the XIB, just to read the values.
  • reading the XIB file itself to pick out the values without creating an instance.

As annoyed as I am by the need to duplicate XIB properties as c开发者_StackOverflowonstants, I haven't had (or made) the time to implement either approach.

Has anyone else come up with a viable solution, or to you just live with the duplication of constants? Which of the above approaches do you think is better (as in safer)?

Thanks.


I take the a "garbage instance" approach, caching both the nibs and the heights:

-(NSNib *)nibWithName:(NSString *)nibName {
    // Load the nib, or fetch it if we've already loaded it, then instantiate its contents
    NSNib *nib = [_itemViewNibs objectForKey:nibName];
    if (!nib) {
        nib = [[NSNib alloc] initWithNibNamed:nibName bundle:nil];
        [_itemViewNibs setObject:nib forKey:nibName];
    }
    return nib;
}

- (NSTableCellView *)firstTableCellInstantiatedFromNibWithName:(NSString *)nibName {
    NSArray *nibObjects;

    NSNib *nib = [self nibWithName:nibName];

    if (![nib instantiateNibWithOwner:self topLevelObjects:&nibObjects]) return nil;

    for (id obj in nibObjects)
        if ([obj isKindOfClass:[NSTableCellView class]])
            return (NSTableCellView *)obj;

    return nil;
}

- (CGFloat)tableCellHeightForNibName:(NSString *)nibName {
    NSNumber *height = [_itemViewHeights objectForKey:nibName];

    if (! height) {    
        NSTableCellView *view = [self firstTableCellInstantiatedFromNibWithName:nibName];
        height = [NSNumber numberWithFloat:view.frame.size.height];
        [_itemViewHeights setObject:height forKey:nibName];
    }

    return height.floatValue;
}

...

CGFloat height = [self tableCellHeightForNibName:item.nibName];

...

view = [self firstTableCellInstantiatedFromNibWithName:item.nibName];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜