使用自动布局将 UITableView 的高度设置为其内容的高度

Set UITableView's height to the height of its content with Auto Layout

我有一个视图,其中有两个标签和一个 Table 视图。我希望标签 1 始终位于 Table 视图上方,标签 2 始终位于 Table 视图下方。问题是 Table 视图需要自动调整大小,这意味着增加或减少高度。

现在我有一个约束说 Table 视图的高度总是等于 85 和一个 @IBOutlet 到我可以改变常量的高度约束。

我想我需要将常量更改为所有单元格的高度,但我不确定该怎么做。

您必须在 UIViewController 中覆盖 updateViewConstraints() 并将高度约束的常量设置为 tableView.contentSize.height:

override func updateViewConstraints() {
    tableHeightConstraint.constant = tableView.contentSize.height
    super.updateViewConstraints()
}

然后你必须确保 Label2 有一个顶部约束,即 greaterThanOrEqual 到 table 视图的底部。并且您还必须将 table 视图的高度约束的优先级从 Required 更改为 High 以避免在 table 视图的 contentHeight 大于可用时约束冲突身高。

还有另一种方法可以做到这一点。 您可以在 table 视图 contentSize 变量上添加观察者,并在 table 视图内容发生变化时添加自身大小。

@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var tableHeightConstraint: NSLayoutConstraint!

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.new, context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    tableView.layer.removeAllAnimations()
    tableHeightConstraint.constant = tableView.contentSize.height
    UIView.animate(withDuration: 0.5) {
        self.updateViewConstraints()
    }

}

在 Swift 4.2 和 Xcode 10.1

这里有两个选项可以根据内容动态设置 UITableView 的高度。

1) 如果您获得内容大小,请在 viewDidLayoutSubviews()

中使用此代码
DispatchQueue.main.async {
  var frame = self.TblView.frame
  frame.size.height = self.TblView.contentSize.height
   self.TblView.frame = frame
}

2) 基于table视图高度约束更新table视图高度。在重新加载 table 视图时得到服务器的响应后编写此代码。

DispatchQueue.main.async {
    self.TblViewHeightConstraint.constant = CGFloat((self.array.count) * 30)//Here 30 is my cell height
     self.TblView.reloadData()
}

为了自动调整 TableView 的高度及其内容大小,请在 ViewController class.

中使用它
//constraintTableViewHeight :- tableview height constraint 

override func viewWillLayoutSubviews() {
    super.updateViewConstraints()
    self.constraintTableViewHeight.constant = self.tableView.contentSize.height
}

并添加这个

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    self.viewWillLayoutSubviews()
}

此代码可以轻松地根据内容大小自动调整 tableview 的高度。

将@nova 的回答扩展到 swift 4

tableViewSizeObservation = tableView.observe(\.contentSize) { [weak self] (tableView, _) in
   tableView.layer.removeAllAnimations()
   self?.tableViewHeightContraint.constant = tableView.contentSize.height
   UIView.animate(withDuration: 0.5) {
         self?.view.updateConstraints()
         self?.view.layoutIfNeeded()
   }
}

deinit {
    tableViewSizeObservation?.invalidate()
}

一种更现代的方法是这样做的:

override func updateViewConstraints() {
    tableView.heightAnchor.constraint(equalToConstant: tableView.contentSize.height).isActive = true
    super.updateViewConstraints()
}

下面的代码对我有用。

  1. Create an outlet for tableViewHeight.
@IBOutlet weak var tableViewHeight: NSLayoutConstraint!
var tableViewHeight: CGFloat = 0  // Dynamically calcualted height of TableView.
  1. For the dynamic height of the cell, I used the below code:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return tableView.estimatedRowHeight
}
  1. For height of the TableView, with dynamic heights of the TableView Cells:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    print(cell.frame.size.height, self.tableViewHeight)
    self.tableViewHeight += cell.frame.size.height
    tableViewBillsHeight.constant = self.tableViewHeight
}

解释:

创建TableView单元格后,我们获取即将显示的单元格的框架高度,并将单元格的高度添加到主TableView。

override func viewDidLayoutSubviews() {
      super.viewDidLayoutSubviews()      
           let contentheight = tableView.contentSize.height
           self.tableHeightConstraint.constant = contentheight
  }