Great news: you're not going crazy. Your stretchable image code is likely perfect. The problem is that UITableView with a grouped style adds extra points to the height of your cells in addition to the value you return in heightForRowAtIndexPath:
So the solution to your problem is to return an adjusted cell height in heightForRowAtIndexPath:
based on the total number of rows in the section:
- (CGFloat)heightForRow:(NSIndexPath *)indexPath {
CGFloat standardHeight = 44.0f;
NSInteger numberOfRowsInSection = [self numberOfRowsInSection:indexPath.section];
if (numberOfRowsInSection == 1) {
standardHeight -= 2;
}
else if (indexPath.row == 0 || indexPath.row == numberOfRowsInSection-1) {
standardHeight -= 1;
}
return standardHeight;
}
Here's a sample image showing how UITableView does this:
As far as I know, only the grouped style table views are affected, and even then the effect changes based on the total number of rows in a given section:
- One Row Adds two points to the cell height (defaults height is 92 pixels on retina).
- Two Rows Adds one point to the height of the first and last rows (90 pixels high each by default on retina).
- Three Rows Adds one point to the height of the first and last rows (90 pixels high each on retina by default). The middle rows are unaffected.
This is so frustrating and has never been documented as far as I know. :-)
Update
The calculations above are for a grouped style table view using the default separator style of UITableViewCellSeparatorStyleSingleLineEtched
. Here's what to do in the other cases (i.e. UITableViewCellSeparatorStyleSingleLine
and UITableViewCellSeparatorStyleNone
):
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat rowHeight = 44.0f;
if (indexPath.row == 0) {
rowHeight -=1;
}
return rowHeight;
}