如何使 UITableView 适合内容的大小

Posted

技术标签:

【中文标题】如何使 UITableView 适合内容的大小【英文标题】:How to make UITableView fit to content's size 【发布时间】:2016-01-27 03:47:21 【问题描述】:

我在表格视图单元格中有一个UITableView(我们称之为tbl_A),其高度是动态的,由UITableViewAutomaticDimension 设置。 tbl_A 的单元格高度也是动态的,我知道 tbl_A 的数据不会太多。所以我希望 tbl_A 滚动禁用,并且它的 frame.size 等于它的内容大小。我试过设置tbl_A的frame.size.height = tbl_A.contentSize.height,可惜高度不对。

顺便说一句,我不必使用UITableView 来完成这项任务。我只是想要一种显示所有数据的方法。有什么建议吗?

这是我想要达到的效果:

【问题讨论】:

我已经尝试了所有可以搜索到的解决方案。 @NicolasMiari 如果你给我一些关键词,我将不胜感激。 @yon 你用的是objective c还是swift? @gikygik 我用 swift 开发 是的,我认为 contentSize 与estimatedRowHeight 相关。所以如果你记录单元格高度并在重新加载后设置它,我认为它会起作用。 【参考方案1】:

简单;)

override var intrinsicContentSize: CGSize 
    return contentSize

【讨论】:

你能详细解释一下吗? 来自文档:Setting this property allows a custom view to communicate to the layout system what size it would like to be based on its content.developer.apple.com/documentation/uikit/uiview/… 不错!这应该是答案 我认为这根本不是一个很好的答案,根本没有细节,我读了另一个答案,它基本上提供了与这个相同的解决方案 - 但写它的人更详细不仅仅是将解决方案称为“简单”。 ***.com/a/52248020/4309446 我明白你在做什么 - 我只是认为它缺乏任何解释,也许在你的答案中添加关于文档的评论?【参考方案2】:

基于@Emad 的回答,但如果 contentSize 发生变化,重要的补充是使内在内容大小无效。

class ContentWrappingTableView: UITableView 

  override var intrinsicContentSize: CGSize 
    return self.contentSize
  

  override var contentSize: CGSize 
    didSet 
        self.invalidateIntrinsicContentSize()
    
  

【讨论】:

Emad 也没有显示将覆盖放在哪里,而是让读者自己弄清楚。【参考方案3】:

只要锁定滚动,就可以使用下面的方式动态匹配tableView的布局:

    let size = actionsViewController.view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
    actionsViewController.view.frame.size = size
    actionsViewController.preferredContentSize = size

以下提供了一种让自动布局为您计算高度并根据您传入的限制为您提供大小的方法。另一种方法可能如下:

    CGFloat leftViewHeight = 0;
    if (self.isExpanded) 
        [self.lineItemLineNumberListTableViewController.tableView layoutIfNeeded];
        UITableView *tableView = self.lineItemLineNumberListTableViewController.tableView;
        CGSize tableViewContentSize = tableView.contentSize;
        leftViewHeight = tableViewContentSize.height;
    

self.leftViewHeightConstraint.constant = leftViewHeight;

我以前使用上述方法来扩展动态调整大小的单元格,其中包含动态子视图。这会在重新加载 tableView 的内容后根据内容大小配置高度约束,以确保在调整大小之前加载内容。

【讨论】:

【参考方案4】:

1) 在你的类中添加对约束的引用:

var heightC: NSLayoutConstraint!

2) 禁用滚动并添加高度约束:

tableView.scrollEnabled = false
heightC = tableView.autoSetDimension(.Height, toSize: 20) // using PureLayout library

3) 覆盖控制器的 viewDidLayoutSubviews:

override func viewDidLayoutSubviews() 
    super.viewDidLayoutSubviews()
    heightC.constant = tableView.contentSize.height

并将高度约束“常量”属性设置为 tableview 内容高度。

4) 在数据刷新时(例如,当项目数从 0 变为更多时)只需强制主控制器视图进行布局:

view.setNeedsLayout()

【讨论】:

【参考方案5】:
    对于您的情况,您还可以使用 scrollView。 在添加每个子单元格的滚动视图中,通过添加每个子单元格的高度来跟踪每个子单元格(将变量作为 referenceHeight) 最终通过计算高度(referenceHeight)设置滚动视图高度

【讨论】:

【参考方案6】:

下面是查找tableView的内容大小的方法。

- (CGFloat)tableViewHeightOfTable:(UITableView *)table

   [table layoutIfNeeded];
   return [table contentSize].height;

确保在重新加载表格后调用此方法,如下面的代码。

[YourTable reloadData];
YourTable.frame.size.height = [self tableViewHeightOfTable:YourTable];

【讨论】:

我认为这个contentSize 是根据estimatedRowHeight 计算出来的,这是不准确的。最后,我使用了 OAStackView 作为我的容器视图。 您能详细分享您的解决方案吗?我正在为同样的问题而苦苦挣扎。【参考方案7】:

在您的情况下,tableview 是最好的解决方案,您可以使用不同的 uitableviewcells 和部分,并可以将其加载到 cellForRowAtIndexPath 中。

【讨论】:

以上是关于如何使 UITableView 适合内容的大小的主要内容,如果未能解决你的问题,请参考以下文章

如何使添加到 UITableViewCell 内容视图的 UIView 适合其范围?

如何使用 AutoLayout 使 UITableView 适合屏幕

是否可以继承 UITableView 并根据单元格的数量使其高度具有内在的内容大小?

调整图像大小以适合 xcode 故事板中的 Ui 图像视图

问:如何更改 UITableView 中的单元格大小,以显示所有标签?

如何使 UITableView 不改变 imageView 的框架,或调整图像大小以填充框架大小?