Search code examples
iosuitableviewindexingcellautoresize

iOS UITableView AutoSizing Cell with Section Index


I have an app where I load a large plist file in a tableview. This plist file is as a book. It contains chapters and lines. Each row has different length depending on the line length and therefore I need to resize the cell automatically.

I am using storyboard and standard tableview and cell. Cell style=basic and the cell label is set to text=plain lines=0 linebreaks=wordwrap

Up to there, no problem resizing the cell height to the proper size. As the cell height is defined before the text is inserted in the label we have to do it by the well known method of using CGsize and I do it like that (it's working fine)

- (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;
}

The problem is the hardcoding depending on the index. For now I have 3 possibilites.

  • No index
  • Index with numbers below 10
  • Index with numbers below 100

and in the code this part

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

is the hardcoding depending on the 3 possibilities.

I find this was of doing weird, especially if apple will start to deliver more different screen sizes.

QUESTION

How can I get the index width at runtime to determine my label width ?

For example i would like to program something like screen.width - index-width to get the label width.

Or any other that should allow it to be dynamical and no more statically hardcoded.


Solution

  • Unfortunately there is no (standard) way you can directly access the section index subview. However, you can use the methods for calculating the CGSize of text to determine dynamically the width of the section index.

    You could determine all possible strings to be returned by sectionIndexTitlesForTableView: beforehand and calculate the necessary size, perhaps padding with some extra pixels left and right. Maybe it is necessary to make some experiments to determine the correct font and size.

    Now your approach with something like screenSize.width - textSize.width - 2*PADDING should be viable. The only hardcoded thing is now the padding, which should not break things when new screen sizes are introduced.