How to set the width of a cell in a UITableView in grouped style

I have been working on this for about 2 days, so i thought i share my learnings with you.

The question is: Is it possible to make the width of a cell in a grouped UITableView smaller?

The answer is: No.

But there are two ways you can get around this problem.

Solution #1: A thinner table It is possible to change the frame of the tableView, so that the table will be smaller. This will result in UITableView rendering the cell inside with the reduced width.

A solution for this can look like this:

-(void)viewWillAppear:(BOOL)animated
{
    CGFloat tableBorderLeft = 20;
    CGFloat tableBorderRight = 20;

    CGRect tableRect = self.view.frame;
    tableRect.origin.x += tableBorderLeft; // make the table begin a few pixels right from its origin
    tableRect.size.width -= tableBorderLeft + tableBorderRight; // reduce the width of the table
    tableView.frame = tableRect;
}

Solution #2: Having cells rendered by images

This solution is described here: http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html

I hope this information is helpful to you. It took me about 2 days to try a lot of possibilities. This is what was left.


A better and cleaner way to achieve this is subclassing UITableViewCell and overriding its -setFrame: method like this:

- (void)setFrame:(CGRect)frame {
    frame.origin.x += inset;
    frame.size.width -= 2 * inset;
    [super setFrame:frame];
}

Why is it better? Because the other two are worse.

  1. Adjust table view width in -viewWillAppear:

    First of all, this is unreliable, the superview or parent view controller may adjust table view frame further after -viewWillAppear: is called. Of course, you can subclass and override -setFrame: for your UITableView just like what I do here for UITableViewCells. However, subclassing UITableViewCells is a much common, light, and Apple way.

    Secondly, if your UITableView have backgroundView, you don't want its backgroundView be narrowed down together. Keeping backgroundView width while narrow down UITableView width is not trivial work, not to mention that expanding subviews beyond its superview is not a very elegant thing to do in the first place.

  2. Custom cell rendering to fake a narrower width

    To do this, you have to prepare special background images with horizontal margins, and you have to layout subviews of cells yourself to accommodate the margins. In comparison, if you simply adjust the width of the whole cell, autoresizing will do all the works for you.


To do this in Swift, which does not provide methods to set variables, you'll have to override the setter for frame. Originally posted (at least where I found it) here

override var frame: CGRect {
    get {
        return super.frame
    }
    set (newFrame) {
        let inset: CGFloat = 15
        var frame = newFrame
        frame.origin.x += inset
        frame.size.width -= 2 * inset
        super.frame = frame
    }
}