动态UITableView高度

时间:2015-12-23 06:00:55

标签: ios swift uitableview

我想设置UITableView以匹配表视图中所有内容的高度。

这是我的故事板

enter image description here

这个问题是顶部和底部的ImageView在屏幕上始终是静态的。

enter image description here

假设桌面视图中有10个项目,但由于屏幕尺寸限制,只有7个项目显示。我希望在用户能够看到底部的ImageView之前显示所有10个。 (顺便说一下,所有3个视图,即图像视图和tableview都在uiscrollview中)

IDEAL

enter image description here

我必须处理的一些其他限制是表视图中的项目数是动态的,这意味着它可以是任何通常小于10的数量,我稍后将从api中检索。根据内容,细胞高度也是动态的。

我刚刚开始使用一些简单的代码

class ExampleViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
      @IBOutlet weak var tableView: UITableView!

  var items: [String] = [
    "Item 01", "Item 02", "Item 03", "Item 04", "Item 05",
    "Item 06", "Item 07", "Item 08", "Item 09", "Item 10"]

  override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
  }

  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.items.count;
  }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
    cell.textLabel?.text = self.items[indexPath.row]
    return cell
  }

}

13 个答案:

答案 0 :(得分:10)

  1. 将您的UITableView子类化以将intrinsicContentSize重写为其contentSize,如下所示:

    override var intrinsicContentSize: CGSize {
        return contentSize
    }
    
  2. 然后为您的表使用自动行高,因此您的exampleViewController的viewDidLoad将具有:

    tableView.estimatedRowHeight = 44
    

    UITableViewDelegate函数:

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    
  3. 当您从API接收数据并重新加载表格时,只需致电:

    tableView.invalidateIntrinsicContentSize()
    

    这将告诉您的表格将其自身调整为与其内容相同的大小(因为覆盖),并根据需要移动底部图像。

  4. 如果你的故事板发出错误,说UIScrollView的高度不明确,因为UITableView上没有高度限制,请选择你的UITableView并在Size Inspector中给它一个占位符内在大小。

答案 1 :(得分:4)

您需要将IBOutlet设置为设置NSLayoutConstraint高度的tableView(首先需要使用任何值创建高度约束,无关紧要)然后按住Ctrl键将其拖动到您的班级文件

enter image description here

然后在您的viewWillAppear中,您必须计算tableView高度并进行设置。像这样:

var tableViewHeight:CGFloat = 0;
for (var i = tableView(self.tableView , numberOfRowsInSection: 0) - 1; i>0; i-=1 ){
    tableViewHeight = height + tableView(self.tableView, heightForRowAtIndexPath: NSIndexPath(forRow: i, inSection: 0) )
}
tableViewHeightLayout.constant = tableViewHeight

这就是它。这将为您提供scrollView内容大小,不应引发任何警告。

答案 2 :(得分:2)

使用子分类技术的答案不完整。您还应该像这样覆盖layoutSubviews()

public class DynamicSizeTableView: UITableView
{
    override public func layoutSubviews() {
        super.layoutSubviews()
        if bounds.size != intrinsicContentSize {
            invalidateIntrinsicContentSize()
        }
    }

    override public var intrinsicContentSize: CGSize {
        return contentSize
    }
}

答案 3 :(得分:2)

这是我在生产应用中使用的:

斯威夫特 5,2021 年

import UIKit

class DynamicTableView: UITableView {

    /// Will assign automatic dimension to the rowHeight variable
    /// Will asign the value of this variable to estimated row height.
    var dynamicRowHeight: CGFloat = UITableView.automaticDimension {
        didSet {
            rowHeight = UITableView.automaticDimension
            estimatedRowHeight = dynamicRowHeight
        }
    }

    public override var intrinsicContentSize: CGSize { contentSize }

    public override func layoutSubviews() {
        super.layoutSubviews()
        if !bounds.size.equalTo(intrinsicContentSize) {
            invalidateIntrinsicContentSize()
        }
    }
}

答案 4 :(得分:1)

在这种情况下,不要让你的底部单元格成为静态,使其成为表格视图的一部分,并使用表格视图委托方法在最后一行插入此底部图像 - Class

答案 5 :(得分:1)

在这种情况下,在表格页脚视图中添加底部imageView(红色)。

要在UITableView中添加页脚视图,您可以使用:

tableViewObj.tableFooterView = footerViewObj;

答案 6 :(得分:1)

您可能必须实现表视图内在内容大小。请检查此answer以查看是否有帮助。

我记得有这个问题,甚至创建了一个自定义的UITableView子类。

#import "IntrinsicTableView.h"

@implementation IntrinsicTableView

#pragma mark - UIView

- (CGSize)intrinsicContentSize
{
    return CGSizeMake(UIViewNoIntrinsicMetric, self.contentSize.height);
}

#pragma mark - UITableView

- (void)endUpdates
{
    [super endUpdates];
    [self invalidateIntrinsicContentSize];
}

- (void)reloadData
{
    [super reloadData];
    [self invalidateIntrinsicContentSize];
}

- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
    [super reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation];
    [self invalidateIntrinsicContentSize];
}

- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
{
    [super reloadSections:sections withRowAnimation:animation];
    [self invalidateIntrinsicContentSize];
}

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
    [super insertRowsAtIndexPaths:indexPaths withRowAnimation:animation];
    [self invalidateIntrinsicContentSize];
}

- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
{
    [super insertSections:sections withRowAnimation:animation];
    [self invalidateIntrinsicContentSize];
}

- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
    [super deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation];
    [self invalidateIntrinsicContentSize];
}

- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
{
    [super deleteSections:sections withRowAnimation:animation];
    [self invalidateIntrinsicContentSize];
}

@end

答案 7 :(得分:1)

试试这个

in ViewDidLoad

 self.table.estimatedRowHeight = 44.0 ;
self.table.rowHeight = UITableViewAutomaticDimension;

索引路径行的高度

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;}

答案 8 :(得分:1)

更新Swift 4  这段代码工作得很好

var items = [
    "Item 01", "Item 02", "Item 03", "Item 04", "Item 05",
    "Item 06", "Item 07", "Item 08", "Item 09", "Item 10"]

 tableViewHeightLayout.constant = CGFloat(items.count) * 
   tableViewHeightLayout.constant
 yourtableView.layoutIfNeeded()

答案 9 :(得分:0)

基于Xamarin编写的解决方案@nikans

[Register(nameof(DynamicSizeTableView)), DesignTimeVisible(true)]
public class DynamicSizeTableView : UITableView
{
    public override void LayoutSubviews()
    {
        base.LayoutSubviews();
        if (Bounds.Size != IntrinsicContentSize)
            InvalidateIntrinsicContentSize();
    }

    public override CGSize IntrinsicContentSize => ContentSize;

    public DynamicSizeTableView(CGRect frame) : base(frame) { }

    public DynamicSizeTableView(IntPtr handle) : base(handle) { }
}

答案 10 :(得分:0)

更新Swift5。添加maxHeight,以便您可以指定tableView的高度

class SelfSizingTableView: UITableView {
    var maxHeight = CGFloat.infinity

    override var contentSize: CGSize {
        didSet {
            invalidateIntrinsicContentSize()
            setNeedsLayout()
        }
    }

    override var intrinsicContentSize: CGSize {
        let height = min(maxHeight, contentSize.height)
        return CGSize(width: contentSize.width, height: height)
    }
}

答案 11 :(得分:0)

这里很简单。

第一步:为table view设置高度约束

第 2 步:控制拖动约束

第 3 步: 在返回行数之前。在 numberOfRowsInSection 方法中,做

tableViewHeightConstraint.constant = tableView.rowHeight * CGFloat(someArray.count)

答案 12 :(得分:-1)

基于@ rr1g0的解决方案

已于2020年为Swift 5更新,并且也可用于带有部分的TableViews。

为tableView创建高度约束并为其创建出口。在 viewDidLayoutSubviews()中,使用以下代码:

var tableViewHeight: CGFloat = 0

for section in 0..<tableView.numberOfSections {
    for row in 0..<tableView.numberOfRows(inSection: section) {
        tableViewHeight += tableView(tableView, heightForRowAt: IndexPath(row: row, section: section))
    }
}

tableViewHeightConstraint.constant = tableViewHeight