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


107

我已经为此工作了大约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

希望这些信息对您有所帮助。我花了大约2天的时间尝试了很多可能性。这就是剩下的。


3
我认为这应该设置为第二行的问题(“问题是:...”),然后将解决方案1和解决方案2发布为两个单独的答案,其中一个被接受。然后,如果其他用户添加了自己的答案,而其中之一最终变得更好,则可以稍后更改接受的答案。
GeneralMike 2013年

Answers:


226

实现此目的的更好,更干净的方法是将UITableViewCell子类化并覆盖其-setFrame:方法,如下所示:

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

为什么会更好?因为其他两个更糟。

  1. 调整中的表格视图宽度 -viewWillAppear:

    首先,这是不可靠的,在-viewWillAppear:调用后,超级视图或父视图控制器可能会进一步调整表视图框架。当然,您可以-setFrame:为UITableView 子类化和重写,就像我在这里为UITableViewCells所做的一样。但是,对UITableViewCells进行子类化是一种非常普遍,轻便和Apple的方式。

    其次,如果您的UITableView具有backgroundView,则不希望将backgroundView的范围缩小到一起。在缩小UITableView宽度的同时保持backgroundView宽度并不是一件容易的事,更不用说首先将子视图扩展到其Superview之外并不是一件很优雅的事情。

  2. 自定义单元格渲染以伪造更窄的宽度

    为此,您必须准备带有水平边距的特殊背景图像,并且必须自己布置单元格的子视图以容纳边距。相比之下,如果您只是调整整个单元格的宽度,则自动调整大小将为您完成所有工作。


2
这是一个很好且优雅的解决方案,我在一个类别中做到了:)我还要注意,对象越透明,CPU负载就越多:)
mister koz 2011年

11
@misterkoz-提醒您一点:某些iOS控件(肯定是UIDatePicker)在内部使用UITableViewCells,如果您在类别中实现它,则会中断。
Clafou 2012年

7
尝试在编辑模式下删除单元格时,此方法在iOS8中似乎不起作用。当您进入/退出编辑模式时,setFrame被调用,因此单元格不断缩小。有什么解决办法吗?
约翰·鲍姆

3
@JohnBaum这可能帮助(至少在我的情况下,它的工作原理):stackoverflow.com/questions/25911484/ios-8-cell-resizing/...
HashtagMarkus

2
这个解决方案确实是天​​赐之物。如果有人想知道如何做同样在迅速- reddit.com/r/swift/comments/2fr849/...
SYSUSER

16

要在不提供设置变量方法的Swift中执行此操作,您必须覆盖的setter frame。原帖(至少在我找到它)在这里

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

快速工作
Simon McNeil

9

如果没有任何效果,您可以尝试一下

使单元格的背景色为纯色,然后放置所需大小的单元格图像。如果要在该单元格上显示一些文本,请在图像上方放置一个标签。不要忘记将标签的背景色也设置为透明色。


8

我发现接受的解决方案在旋转时不起作用。为了实现具有固定宽度和灵活边距的UITableViewCells,我将上述解决方案调整为以下内容:

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

每当设备旋转时都会调用该方法,因此单元始终处于居中状态。


0

旋转屏幕时会调用一种方法:viewWillTransitionToSize

在这里您应该调整框架的大小。参见示例。根据需要更改框架坐标。

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

-2

我在做

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

这对我有用


-6

在.h文件中,添加委托'UITableViewDataSource'

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

4
他想设定宽度而不是高度
Christopher Pickslay 2010年

哦,哦。不便之处,敬请见谅。
bharath gangupalli

ü误解的问题和u回答高度,你知道,因为我在寻找什么样的工作适合我身高不是width..thanks的答案
普加
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.