首页 > 解决方案 > 如何通过情节提要中的组件自己制作容器视图大小

问题描述

我在故事板中添加了一个容器视图,该视图UIViewController由单独的UIViewController. 这个容器视图需要有一个与之关联的高度,以便正确地布置项目。但是,此容器视图的高度是动态的,因为它包含UITextView其他项目。以前,当我不使用容器视图时,自动布局会为我计算项目的高度。现在我已将所有内容移至容器视图,这似乎是不可能的。我是否必须手动计算容器视图的高度并将其应用于约束,或者有没有办法让自动布局处理它?

标签: iosswift

解决方案


你可以这样做,但你需要一点代码。

当 aUIViewController嵌入到容器视图中时,它的“根视图”.translatesAutoresizingMaskIntoConstraints设置为 true,并且它的框架自动设置为容器视图的边界。

如果您的嵌入式 VC 已将约束设置为正确调整自身大小,则可以.translatesAutoresizingMaskIntoConstraints在加载时禁用其根视图。

举个例子,假设我们有这个布局,并且“内容 VC”中的标签将有可变数量的行:

在此处输入图像描述

我们希望容器视图自动更改其高度,以便所有文本都适合。但是,如果我们添加 10 行文本,“默认”结果将是:

在此处输入图像描述

所以,我们给容器视图 Top/Leading/Trailing 约束8(所以我们在侧面有一点填充)和一个 Height 约束128......但是我们将PriorityHeight 约束更改为250 (Low). 这满足了 IB,但在运行时为我们提供了高度的灵活性。

在我们的“内容 VC”中,我们添加了一个标签并将它的 Top/Leading/Trailing/Bottom 全部限制为8(同样,只是为了一些填充),当然,行数设置为0.

现在,在我们的主 VC 中,我们在嵌入式 VC 的根视图上实现prepare(for segue...)和禁用:.translatesAutoresizingMaskIntoConstraints

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    if let childViewController = segue.destination as? MyContentViewController {
        childViewController.view.translatesAutoresizingMaskIntoConstraints = false
    }
}

现在,在运行时,我们标签的固有高度将增加其父视图(根视图)的高度,这将覆盖容器视图的低优先级高度常量,从而导致:

在此处输入图像描述

以下是两个 VC 的完整代码:

import UIKit

class MyContentViewController: UIViewController {

    @IBOutlet var theLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        // add 10 lines of text to the label
        theLabel.text = (1...10).map({ "Line \($0)" }).joined(separator: "\n")

    }

}

class ContainerContentViewController: UIViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        if let childViewController = segue.destination as? MyContentViewController {
            childViewController.view.translatesAutoresizingMaskIntoConstraints = false
        }
    }

}

推荐阅读