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

IosIphoneUitableviewWidth

Ios Problem Overview


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.

Ios Solutions


Solution 1 - Ios

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.

  1. 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.

Solution 2 - Ios

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
    }
}

Solution 3 - Ios

If nothing works you can try this

Make the background colour of the cell as clear color and then put an image of the cell with required size. If you want to display some text on that cell put a label above the image. Don't forget to set the background color of the label also to clear color.

Solution 4 - Ios

I found the accepted solution didn't work upon rotation. To achieve UITableViewCells with fixed widths & flexible margins I just adapted the above solution to the following:

- (void)setFrame:(CGRect)frame {

    if (self.superview) {
        float cellWidth = 500.0;
        frame.origin.x = (self.superview.frame.size.width - cellWidth) / 2;
        frame.size.width = cellWidth;
    }

    [super setFrame:frame];
}

The method gets called whenever the device rotates, so the cells will always be centered.

Solution 5 - Ios

There is a method that is called when the screen is rotated : viewWillTransitionToSize

This is where you should resize the frame. See example. Change the frame coords as you need to.

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {
        int x = 0;
        int y = 0;
        self.tableView.frame = CGRectMake(x, y, 320, self.tableView.frame.size.height);
    }];
}

Solution 6 - Ios

i do it in

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    CGFloat tableBorderLeft = self.view.frame.origin.x + 10;
    CGFloat tableBorderRight = self.view.frame.size.width - 20;

    CGRect tableRect = self.view.frame;
    tableRect.origin.x = tableBorderLeft; 
    tableRect.size.width = tableBorderRight; 
    tableView.frame = tableRect;
}

And this worked for me

Solution 7 - Ios

In .h file add the delegate 'UITableViewDataSource'

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ 
    return size;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTomenView Question on Stackoverflow
Solution 1 - Iosan0View Answer on Stackoverflow
Solution 2 - IosJuJoDiView Answer on Stackoverflow
Solution 3 - IosincludeMeView Answer on Stackoverflow
Solution 4 - IosGrahamView Answer on Stackoverflow
Solution 5 - IosGuyView Answer on Stackoverflow
Solution 6 - IosLều Đức QuýView Answer on Stackoverflow
Solution 7 - Iosbharath gangupalliView Answer on Stackoverflow