嵌入了 containerView 的静态单元格上的动态高度

Dynamic height on a static cell with containerView embedded

我想使用自动布局实现期望的行为(或者如果这不可能使用委托或其他东西)。我有一个带有一个静态单元格的 tableView,这个单元格有一个 containerView,它有一个带有动态原型单元格的 tableViewController。

我想要的是能够使用自动布局来动态设置嵌入了容器视图的静态单元格的高度。

这是故事板:

这些是我的约束条件(带有容器视图的 contentView 的静态单元格):

在静态单元格中有 containerView 的 viewController 我所拥有的是 ViewDidLoad 方法:

override func viewDidLoad() {
    super.viewDidLoad()

    courseDetailTableView.estimatedRowHeight = 200
    courseDetailTableView.rowHeight = UITableViewAutomaticDimension
}

并将 tableView 的委托与 staticCell 一起使用:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

但是有了这个静态单元格的高度真的很小...这意味着自动布局无法仅使用我设置的约束来设置其内容的高度..我只说了约束因为如果我在 containerView 的 contentView 上再设置一个约束,将高度设置为 400,那么该单元格的高度就是 400..

我只是想知道是否有自动布局的方法来设置静态单元格的高度以匹配 containerView 的高度。

我知道也许使用一个委托首先计算 containerView 的高度并使用这个高度来设置 heightForRow 可能可行我想知道是否有更简单的方法

非常感谢。

所以如果我正确理解你实际上有这些限制:

  • ContentView.bottom = ContainerView.bottom
  • ContentView.trailing = ContainerView.trailing + 标准
  • ContainerView.leading = ContentView.leading + 标准
  • ContainerView.top = ContentView.top

基本上你想要的是这个约束:

  • ContentView.height = ContainerView.height 对吧?但是如果你把它放在一个非常小的单元格中?

如果是这种情况,您可以尝试设置一个约束来固定 containerView 的最小高度,如下所示:

  • ContainerView.height >= 400 // 例如高度至少为 400

那么你可以尝试为等高设置一个可选约束:

  • ContentView.height = ContainerView.height(优先级 249 或低)

通过降低你所说的约束的优先级 "I have this extra constraint, it will be great if the contentView matches the containerView height if not keep going or approximate to it"。

这里是关于 AutoLayout 的更多信息AutooLayout Understanding

P.S : 你不需要实现 tableView:heightForRowAtIndexPath: 通过返回 automaticDimension 委托方法。

我只想为面临同样问题的人回答我自己的问题。它不必与静态单元格一起使用,此答案适用于静态单元格和动态单元格。

你要做的就是在containerViewController设置一个属性或者一个计算高度的方法(别忘了要求layoutIfNeeded)

func tableViewHeight() -> CGFloat {
    tableView.layoutIfNeeded()
    return tableView.contentSize.height
}

然后在主视图控制器(具有嵌入 containerViewController 的单元格的控制器)中,您必须保存对 containerViewController 的引用,例如在准备 segue 方法中,如下所示:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "containerSegue" {
        guard let containerVC = segue.destination as? SessionCoordinatorController else { return }
        sessionController = containerVC
    }
}

然后在 UITableView heightForRowAt 的委托方法中请求容器高度,就像这样(在 masterViewController 中):

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    guard let height = sessionController?.tableViewHeight() else { return UITableViewAutomaticDimension }
    return height
}

就是这样

不要忘记在 containerViewController

中将 tableView.isScrollEnabled 添加为 false