从故事板中检索自定义原型单元格高度? [英] Retrieve custom prototype cell height from storyboard?
问题描述
使用动态原型在故事板上指定 UITableView
内容时,可以将行高属性设置为自定义。
When using "Dynamic Prototypes" for specifying UITableView
content on the storyboard, there is a "Row Height" property that can be set to Custom.
实例化单元格时,不考虑此自定义行高。这是有道理的,因为我使用的原型单元是由我的应用程序代码在要实例化单元时决定的。在计算布局时实例化所有单元格会引入性能损失,所以我理解为什么不能这样做。
When instantiating cells, this custom row height is not taken into account. This makes sense, since which prototype cell I use is decided by my application code at the time when the cell is to be instantiated. To instantiate all cells when calculating layout would introduce a performance penalty, so I understand why that cannot be done.
那么问题,我可以以某种方式检索给定单元格的高度重用标识符,例如
The question then, can I somehow retrieve the height given a cell reuse identifier, e.g.
[myTableView heightForCellWithReuseIdentifier:@"MyCellPrototype"];
还是那条线上的东西?或者我是否必须在应用程序代码中复制显式行高,以及后面的维护负担?
or something along that line? Or do I have to duplicate the explicit row heights in my application code, with the maintenance burden that follows?
在@TimothyMoose的帮助下解决:
高度存储在单元格本身中,这意味着获得高度的唯一方法是实例化原型。这样做的一种方法是将细胞预先出列在正常细胞回调方法之外。这是我的小POC,它起作用:
The heights are stored in the cells themselves, which means the only way of getting the heights is to instantiate the prototypes. One way of doing this is to pre-dequeue the cells outside of the normal cell callback method. Here is my small POC, which works:
#import "ViewController.h"
@interface ViewController () {
NSDictionary* heights;
}
@end
@implementation ViewController
- (NSString*) _reusableIdentifierForIndexPath:(NSIndexPath *)indexPath
{
return [NSString stringWithFormat:@"C%d", indexPath.row];
}
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(!heights) {
NSMutableDictionary* hts = [NSMutableDictionary dictionary];
for(NSString* reusableIdentifier in [NSArray arrayWithObjects:@"C0", @"C1", @"C2", nil]) {
CGFloat height = [[tableView dequeueReusableCellWithIdentifier:reusableIdentifier] bounds].size.height;
hts[reusableIdentifier] = [NSNumber numberWithFloat:height];
}
heights = [hts copy];
}
NSString* prototype = [self _reusableIdentifierForIndexPath:indexPath];
return [heights[prototype] floatValue];
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString* prototype = [self _reusableIdentifierForIndexPath:indexPath];
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:prototype];
return cell;
}
@end
推荐答案
对于静态(非数据驱动)高度,您只需将单元格出列一次并存储高度:
For static (non-data-driven) height, you can just dequeue the cell once and store the height:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSNumber *height;
if (!height) {
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"MyCustomCell"];
height = @(cell.bounds.size.height);
}
return [height floatValue];
}
对于动态(数据驱动)高度,您可以存储原型单元格视图控制器并向单元格的类添加一个计算高度的方法,同时考虑原型实例的默认内容,例如子视图放置,字体等:
For dynamic (data-driven) height, you can store a prototype cell in the view controller and add a method to the cell's class that calculates the height, taking into account the default content of the prototype instance, such as subview placement, fonts, etc.:
- (MyCustomCell *)prototypeCell
{
if (!_prototypeCell) {
_prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:@"MyCustomCell"];
}
return _prototypeCell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Data for the cell, e.g. text for label
id myData = [self myDataForIndexPath:indexPath];
// Prototype knows how to calculate its height for the given data
return [self.prototypeCell myHeightForData:myData];
}
当然,如果你使用自定义高度,你可能有多个单元格原型,所以你将它们存储在字典或其他东西。
Of course, if you're using custom height, you probably have multiple cell prototypes, so you'd store them in a dictionary or something.
据我所知,表视图不会尝试重用原型,大概是因为它在 cellForRowAtIndexPath:
之外出列。这种方法对我们来说非常有效,因为它允许设计人员修改故事板中的单元格布局,而无需更改任何代码。
As far as I can tell, the table view doesn't attempt to reuse the prototype, presumably because it was dequeued outside of cellForRowAtIndexPath:
. This approach has worked very well for us because it allows the designer to modify cells layouts in the storyboard without requiring any code changes.
编辑:澄清了示例代码的含义,并为静态高度的情况添加了一个示例。
clarified the meaning of sample code and added an example for the case of static height.
这篇关于从故事板中检索自定义原型单元格高度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!