如何在 UITableView 中以分组样式设置单元格的宽度

我已经为此工作了大约2天,所以我想我与你分享我的经验教训。

问题是: 是否有可能使分组 UITableView 中的单元格的宽度变小?

答案是: 不。

但是有两种方法可以解决这个问题。

解决方案1: 更薄的桌子 可以更改 tableView 的框架,以使表更小。这将导致 UITableView 以缩小的宽度呈现内部的单元格。

解决这个问题的方法可以是这样的:

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

解决方案 # 2: 使用图像呈现单元格

这里描述了这种解决方案: http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html

我希望这个信息对你有帮助。我花了两天时间尝试了很多可能性。这是剩下的。

96851 次浏览

In .h file add the delegate 'UITableViewDataSource'

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

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.

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.

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.

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

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

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);
}];
}