具有截面索引的iOS UITableView自动调整单元格

时间:2012-09-20 10:28:53

标签: ios uitableview indexing cell autoresize

我有一个应用程序,我在tableview中加载一个大的plist文件。这个plist文件就像一本书。它包含章节和行。每行的长度取决于行长度,因此我需要自动调整单元格大小。

我正在使用故事板和标准tableview和单元格。单元格样式=基本,单元格标签设置为text = plain lines = 0 linebreaks = wordwrap

到那里,没有问题将单元格高度调整到合适的大小。由于在文本插入标签之前定义了单元格高度,我们必须通过使用CGsize的众所周知的方法来完成它,我这样做(它工作正常)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:
      (NSIndexPath*)indexPath
{
    NSUInteger section = [indexPath section];
    NSString *key = [chapters objectAtIndex:section];
    NSArray *linesSection = [lines objectForKey:key];
    NSString* theText =  [linesSection objectAtIndex:indexPath.row];

    int labelWidth = LW_CHAPTERINDEX_10;
    if (chapters.count < 100){
        if (chapters.count < NB_MIN_CHAP){
            labelWidth = LABELWIDTH;
        } else {
            labelWidth = LW_CHAPTERINDEX_10;
        }
    }

    CGSize textSize = [theText sizeWithFont:[UIFont systemFontOfSize:14]
        constrainedToSize:CGSizeMake(labelWidth, MAXFLOAT) 
        lineBreakMode:UILineBreakModeWordWrap];

    return textSize.height;
}

问题是硬编码取决于索引。现在我有3个可能性。

  • 无索引
  • 数字低于10的索引
  • 数字低于100的索引

在代码中这部分

int labelWidth = LW_CHAPTERINDEX_10;
if (chapters.count < 100){
    if (chapters.count < NB_MIN_CHAP){
        labelWidth = LABELWIDTH;
    } else {
        labelWidth = LW_CHAPTERINDEX_10;
    }
}

是硬编码,取决于3种可能性。

我发现这很奇怪,特别是如果苹果开始提供更多不同的屏幕尺寸。

问题

如何在运行时获取索引宽度以确定我的标签宽度?

例如,我想编写类似screen.width - index-width的内容来获取标签宽度。

或任何其他应该允许它具有动态性并且不再是静态硬编码的。

2 个答案:

答案 0 :(得分:1)

不幸的是,没有(标准)方法可以直接访问节索引子视图。但是,您可以使用这些方法计算文本的CGSize,以动态确定节索引的宽度。

您可以预先确定sectionIndexTitlesForTableView:返回的所有可能的字符串并计算必要的大小,也许可以左右填充一些额外的像素。也许有必要进行一些实验来确定正确的字体和大小。

现在,您使用类似screenSize.width - textSize.width - 2*PADDING的方法应该是可行的。现在唯一的硬编码就是填充,当引入新的屏幕尺寸时,它不应该破坏。

答案 1 :(得分:1)

好的,为了节省其他人几个小时的工作....我费力地测试了各种字体和大小和边距,将它们与带有索引的实际表视图的UIView层次结构转储进行比较,得出这个方法将返回表索引的宽度,以便表视图单元格内容的边界可以计算为table_width - index_width。我将指出,附件视图通常还有另外20个像素的右侧数量。

我还发现在调用AFTER cellForRowAtIndexPath和willDisplayCell方法之前,没有正确设置cell.contentView.bounds,因此在这些调用期间尝试获取值注定会失败。它在viewDidAppear被调用时正确设置。

如果设备语言设置为非英文字母,我不知道如何计算索引宽度。

- (CGFloat) getMaxIndexViewWidth
{
    CGFloat indexMargin = 21.0;   
    NSArray *sectionTitles = [self sectionIndexTitlesForTableView:nil];  //NOTE -- if multiple tables, pass real one in

    CGFloat maxWidth11 = CGFLOAT_MIN;

    for(NSString *title in sectionTitles)
    {
        CGFloat titleWidth11 = [title sizeWithFont:[UIFont  fontWithName:@"Helvetica-Bold" size:11.0f]].width;
        maxWidth11 = MAX(maxWidth11, titleWidth11);     
    }
    return maxWidth11+indexMargin;
}