views:

85

answers:

1

The proper height for my custom UITableViewCells depends on their width. Unfortunately, it is difficult to know the actual content area width of a cell in -tableView:heightForRowAtIndexPath:, since the only information I have to work with is the tableview. Several factors can change the content width so it is not equal to tableView.bounds.size.width; the one I'm struggling with now is the section index. (Another is if the tableview is grouped.)

Is there a good way in general to get the cell content width from just the tableView?

Failing that, is there any way to get the width of the section index, so that I can subtract it from the bounds width? (I don't want to hard code it, since that won't be portable across devices.)

Note: This is not a dup of http://stackoverflow.com/questions/2116847/need-access-to-the-cell-in-the-tableviewheightforrowatindexpath because the solution there is just to use the bounds. Nor is it a dup of http://stackoverflow.com/questions/1352801/get-tableviewheightforrowatindexpath-to-happen-after-tableviewcellforrowatinde since the solution there is to hard code a constant (265.0), which isn't portable across devices.

A: 

Here's what I got working. It's ugly, but it works, at least in all the cases I could find.

- (CGFloat)sectionIndexWidthForSectionIndexTitles:(NSArray *)titles {
  UIFont *sectionIndexFont = [UIFont fontWithName:@"Helvetica-Bold" size:14.0f];
  CGFloat maxWidth = CGFLOAT_MIN;
  for(NSString *title in titles) {
    CGFloat titleWidth = [title sizeWithFont:sectionIndexFont].width;
    maxWidth = MAX(maxWidth, titleWidth);
  }

  CGFloat sectionIndexWidth = 0.0f;
  NSUInteger maxWidthInt = (int)maxWidth;
  switch(maxWidthInt) {
    case 0:
      sectionIndexWidth = 0.0f;
      break;
    case 11:
      sectionIndexWidth = 30.0f;
      break;
    case 12:
      sectionIndexWidth = 31.0f;
      break;
    case 14:
      sectionIndexWidth = 32.0f;
      break;
    default:
      sectionIndexWidth = 0.0f;
      break;
  }

  return sectionIndexWidth;  
}
Josh Bleecher Snyder