Getting the real width of a tableview cell during -tableView:heightForRowAtIndexPath: when there is a section index present
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 th开发者_如何学Pythone 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 Need access to the cell in the tableView:heightForRowAtIndexPath: because the solution there is just to use the bounds. Nor is it a dup of Get tableView:heightForRowAtIndexPath: to happen after tableView:cellForRowAtIndexPath:? since the solution there is to hard code a constant (265.0), which isn't portable across devices.
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;
}
Ok, to save other people a few hours of work....I laboriously tested various fonts and sizes and margins, comparing them to a UIView hierarchy dump of an actual table view with an index, to arrive at this method which will return the width of a table index, so that the bounds of the table view cell content can be calculated as table_width - index_width. I will point out that there is often another 20 pixel right-side amount reserved for an accessory view.
I also discovered that the cell.contentView.bounds is NOT correctly set until AFTER cellForRowAtIndexPath and willDisplayCell methods are called, so trying to grab the value during those calls is doomed to fail. It is set correctly by the time viewDidAppear is called.
I have no idea how to calculate the index width if the device language is set for a non-English alphabet.
- (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;
}
精彩评论