The grouped UITableView places a margin between the edge of the view and the table cells. Annoyingly (for me) this margin is some function of the width of the view.
Grouped TableView Width in Relation to Cell Margin
TBWidth (0 to 20) Left Margin = TBWidth - 10
TBWidth (20 to 400) Left Margin = 10
TBWidth (401 to 546) Left Margin = 31
TBWidth (547 to 716) Left Margin = apx 6% of tableView
TBWidth (717 to 1024) Left Margin = 45
- (float) groupedCellMarginWithTableWidth:(float)tableViewWidth
{
float marginWidth;
if(tableViewWidth > 20)
{
if(tableViewWidth < 400)
{
marginWidth = 10;
}
else
{
marginWidth = MAX(31, MIN(45, tableViewWidth*0.06));
}
}
else
{
marginWidth = tableViewWidth - 10;
}
return marginWidth;
}
I have tried a different approach. But not sure whether it always work. I had a grouped UITableView and needed to make customized Header View. But as you know, when implementing viewForHeader inSection method we can not determine the margins for our created view. So, what I have done is firstly add a CGRect property to ViewController .m file:
@property(nonatomic)CGRect groupedCellRectangle;
and in UITableViewDelegate:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
static BOOL groupFrameInitialized = NO;
if(!groupFrameInitialized){
groupFrameInitialized = YES;
self.groupedCellRectangle = cell.contentView.frame;
}
}
after then, in my viewForHeader inSection method:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(self.groupedCellRectangle.origin.x, 0, self.groupedCellRectangle.size.width, 28)];
[v setBackgroundColor:[UIColor clearColor]];
UILabel *label = [[UILabel alloc] initWithFrame:v.frame];
label.text = @"KAF";
[v addSubview:label];
return v;
}
the result is as I assumed. groupedCellRectangle had successfully stored CGRect value with margin.
The idea behind this approach was UITableView always call viewForHeader method after willDisplay call.
Hope that helps...
By creating (and using!) a subclass of UITableViewCell, you can possibly achieve what you're looking for. Just move the contentview and backgroundview around in layoutsubviews, as in the code sample below which shifts the visible parts of the cell 20pt to the right.
- (void) layoutSubviews
{
NSLog (@"Cell/contentview/backgroundview before:\n%@\n%@\n%@", self, self.contentView, self.backgroundView);
[super layoutSubviews];
CGRect frame = self.backgroundView.frame;
frame.origin.x += 20;
frame.size.width -= 20;
self.backgroundView.frame = frame;
frame = self.contentView.frame;
frame.origin.x += 20;
frame.size.width -= 20;
self.contentView.frame = frame;
NSLog (@"Cell/contentview/backgroundview after:\n%@\n%@\n%@", self, self.contentView, self.backgroundView);
}
More accurate left margin for the 'stretchy' zone instead of the 'apx. 6% calc.'
Side note: the iPad implements additional section top and bottom padding in addition to the left margin padding, it's 10.0f below 400.0f table width and 31.0f otherwise.
-(CGFloat)leftMarginForTableView:(UITableView*)tableView
{
if (tableView.style != UITableViewStyleGrouped) return 0;
CGFloat widthTable = tableView.bounds.size.width;
if (isPhone) return (10.0f);
if (widthTable <= 400.0f) return (10.0f);
if (widthTable <= 546.0f) return (31.0f);
if (widthTable >= 720.0f) return (45.0f);
return (31.0f + ceilf((widthTable - 547.0f)/13.0f));
}
Just in case anyone needs this, the function for the section title left margin when obtained from tableView:titleForHeaderInSection:
seems to be:
- (float)marginForSectionTitleOnGroupedTableView {
float width = self.width;
if (width <= 400) return 19;
else if (width >= 401 && width < 547) return 40;
else if (width >= 547 && width < 560) return 41;
else if (width >= 560 && width < 573) return 42;
else if (width >= 573 && width < 586) return 43;
else if (width >= 586 && width < 599) return 44;
else if (width >= 599 && width < 612) return 45;
else if (width >= 612 && width < 625) return 46;
else if (width >= 625 && width < 639) return 47;
else if (width >= 639 && width < 652) return 48;
else if (width >= 652 && width < 665) return 49;
else if (width >= 665 && width < 678) return 50;
else if (width >= 678 && width < 691) return 51;
else if (width >= 691 && width < 704) return 52;
else if (width >= 704 && width < 717) return 53;
// if (width >= 717)
return 54;
}
For widths greater than 401, the margin seems to be around 7.5% of the table view width; but when trying to align some other view with the section title, the alignment didn't work as expected; so the verbose approach seems to work better.
This is now accessible through a property of UITableViewCell:
@property(nonatomic) UIEdgeInsets separatorInset
Apple Docs - UITableViewCell - seperatorInset