iOS: Frame VS Bounds Or How To Resize Your Basic UITableView Cell

In the last few days, I’ve had to deal a lot with trying to resize a basic UITableViewCell, so that the disclosure indicator is moved more in (since the cell is supposed to be shorter).

So one of my UITableView cells was supposed to look like this:

Screen Shot 2013-08-09 at 6.11.56 AM

Instead of this:

Screen Shot 2013-08-09 at 6.10.53 AM

Yes, I know, it’s a pretty bad design to put a grouped UITableViewCell on a non-grouped UITableViewController, and I got it sorted out, but the initial design I was working on required that some of the cells in my plain tableview were to look smaller than the other cells.

After a lot of pain, I found the solution in resizing the BOUNDS of the cell. You’ve probably noticed that all UIViews have an initWithFrame: method, including UITableViewCells. But bounds are more rarely used, and are very similar to a frame – both are a CGRect, for example.

So what’s the difference? It’s very subtle, but important:

frame

The frame rectangle, which describes the view’s location and size in its superview’s coordinate system.

bounds

The bounds rectangle, which describes the view’s location and size in its own coordinate system.

So if you want to change the position of your cell within it’s superview (the tableview in this case), use the frame. But if you want to shrink or move an element within the view, use the bounds! So in my case, to change the positioning of the standard disclosure indicator, which is a subview on our UITableViewCell view, I just changed the bounds of the UITableViewCell!

To do that, I subclassed my UITableViewCell, and over-wrote the layoutSubviews method in my subclass:

// MyCustomUITableViewCell.h

- (void)layoutSubviews
{
    self.bounds = CGRectMake(self.bounds.origin.x,
                             self.bounds.origin.y,
                             self.bounds.size.width - 50,
                             self.bounds.size.height);

    [super layoutSubviews];
}

Since the standard disclosure indicator is a subview, which has a FRAME (it’s position in relation to it’s superview), it is automatically moved to the correct position on it’s superview (the UITableViewCell), when we change the bounds of the cell.

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.

  • Chen Qin

    Thank you so much.

    I was pulling my hair out with frustration over UITableCell’s refusal to reliably redraw a resized subview even after calling setNeedsDisplay and setNeedsLayout. Setting bound finally force the cell to draw correctly and most importantly, reliably.

  • I would create a container view holding all the sub elements inside the cell, and change this container view ‘s frame instead

  • Anirudha Mahale

    The above doesn’t work for me. Can you please write the correct code again in swift?