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.
I was using Matthew Thomas implementation but it's unreliable (it's broken if you use autorotation in your controllers) and has a lot of hardcoded code... I realized that there is a very simple solution, my implementation is a single line of code:
- (float)cellMargins
{
return self.backgroundView.frame.origin.x * 2;
}
This is far better IMO :)
EDIT: my implementation was unreliable too (it does not work properly when switching to/from editing mode), this is my final implementation (I handled right and left margins separately):
- (float)leftMargin
{
return self.contentView.frame.origin.x;
}
- (float)rightMargin
{
CGRect frame = self.contentView.frame;
float containerWidth = frame.size.width;
float margin = self.frame.size.width - (containerWidth + frame.origin.x);
return margin;
}
- (float)cellMargins
{
return ([self leftMargin] + [self rightMargin]);
}
Updated Matthew Thomas's code for cell margins calculation. Created via UITableView's category. This can be useful, when you need to determine text height in cell, and you dont' know width of that cell.
So, actual cell can be calculated like
cell.width = tableView.width - tableView.cellsMargin * 2;
An here's the code
@implementation UITableView (CellsMargins)
// This is black magic
// from
// http://stackoverflow.com/questions/4708085/how-to-determine-margin-of-a-grouped-uitableview-or-better-how-to-set-it
- (CGFloat)cellsMargin {
// No margins for plain table views
if (self.style == UITableViewStylePlain) {
return 0;
}
// iPhone always have 10 pixels margin
if (! isIPad()) {
return 10;
}
CGFloat tableWidth = self.frame.size.width;
// Really small table
if (tableWidth <= 20) {
return tableWidth - 10;
}
// Average table size
if (tableWidth < 400) {
return 10;
}
// Big tables have complex margin's logic
// Around 6% of table width,
// 31 <= tableWidth * 0.06 <= 45
CGFloat marginWidth = tableWidth * 0.06;
marginWidth = MAX(31, MIN(45, marginWidth));
return marginWidth;
}
@end
I would like to supplement Matthew's answer with a code to set-up fixed margin.
- (void)setFrame:(CGRect)frame
{
CGFloat inset = 15.0;
CGFloat tableWidth = 400.0;
frame.origin.x -= [self groupedCellMarginWithTableWidth:tableWidth] - inset;
frame.size.width = frame.size.width + 2 * ([self groupedCellMarginWithTableWidth:tableWidth] - inset);
[super setFrame:frame];
}
This will set left and right margin for 15.0 while table width may vary.