调整UITableView的高度,使其高度适应总内容大小

16

我遇到了一个很基础的问题。我有一个位于view中的UITableView,我想让这个表格的高度尽可能地高以便显示表格内的所有行。因此,我不想能够滚动,我只想要所有行都显示出来。(行数和height是动态的)。

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize cellSize = [[[_stepsArray objectAtIndex:indexPath.row]content] sizeWithFont:[UIFont boldSystemFontOfSize:18.0f] constrainedToSize:CGSizeMake(528.0f, CGFLOAT_MAX)lineBreakMode:NSLineBreakByWordWrapping];
    return cellSize.height;
}

如果有20行,表格将非常高,但如果只有1行,则会非常小,并且其他内容在下面的19行中都不会显示出来。

6个回答

22

如果我理解得正确,你应该能够将每一行的高度相加,并根据此调整tableview的高度:

CGFloat tableHeight = 0.0f;
for (int i = 0; i < [_stepsArray count]; i ++) {
    tableHeight += [self tableView:self.tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
}
self.tableView.frame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, tableHeight);

在 [tableView reloadData] 之后立即执行此操作。


我从不调用 [tableView reloadData]。那我应该把它放在哪里呢? - abisson
在设置完_stepsArray(我假设它是你的数据源)之后。 - Edwin Iskandar
1
不是说 heightForRowAtIndexPath 会被调用两次吗?而且...没有更简单的方法来做这个吗?我感觉我已经看过很多应用程序,其中表格的高度是基于总行数的..!谢谢! - abisson
它将会被调用两次,但是由于您只是基于字体计算内容大小,所以开销应该相对较小。您还可以尝试在UITableView完成显示后(您可以在- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell )cell forRowAtIndexPath:(NSIndexPath)indexPath)将tableView的框架高度设置为tableView.contentSize.height。 - Edwin Iskandar

6
这里有一种更简单的解决方案:你只需要在你的UITableView上设置sizeToFit,在它被填充完毕之后。如果你通过xib来设置delegatedataSource,你可以在viewDidLoad方法或viewDidAppear方法中完成这个操作,像这样:
- (void)viewDidLoad
{
    [super viewDidLoad];

    [yourTableView sizeToFit];
}

但是,如果您在代码中添加了delegatedataSource,您需要在此之后放置sizeToFit

- (void)someMethod
{
    [yourTableView setDelegate:self];
    [yourTableView setDataSource:self];

    [yourTableView sizeToFit];
}

另外,如果您在某处执行此操作,则必须在 reloadTable 后执行。

这将使您的表格大小调整为其单元格高度之和!


没错DennisWelu,sizeToFit只会考虑行内容,而不是行之间的空格。 - akelec

4
你可以试试这样做:
-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if([indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row){
        NSLog(@"%f",your_tableView.contentSize.height);
    }
}

在Swift 3.0中,
func tableView(_ tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if indexPath.row == tableView.indexPathsForVisibleRows?.last?.row {
        print("\(tableView.contentSize.height)")
    }
}

3
在TableView的contentSize属性上添加一个观察者,并相应地调整frame大小。
在viewDidLoad中添加以下代码行。
[your_tableview addObserver:self forKeyPath:@"contentSize" options:0 context:NULL];

在回调函数中:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
         CGRect frame = your_tableview.frame;
         frame.size = your_tableview.contentSize;
         your_tableview.frame = frame;
    }

希望这能帮到您。

3

在表格上设置高度约束,连接到电源插座,并在您的视图控制器中添加以下内容:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    tableViewHeightContraint.constant = tableView.contentSize.height
}

0
只需要使用 tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];,就可以解决你的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接