在Swift中动态创建uiviewcontroller

Nis*_*han 9 ios swift

我想动态创建UIViewController而不创建类或使用Mainstoryboard.我希望它以编程方式发生.是否可能?我想根据动态数据创建UIViewControllers.

Rob*_*Rob 22

是的,您可以通过编程方式动态创建视图.我知道你说你不想上课,但你真的必须这样做.但关键是你不必让这个类硬编码UI,而是动态地构建它.

因此,您可以子类化UIViewController,但是将动态构建视图所需的数据传递给它,然后实现该loadView方法.不需要NIB或故事板场景.只需view根据动态数据创建并构建子视图."旧版View Controller编程指南"中对此进行了描述.(请注意,该文档的某些部分不再适用,尤其是"卸载"视图讨论.但它确实描述并说明了该loadView过程,该过程仍然可以正常工作.)

构建视图控制器视图的过程如下:

在此输入图像描述

如您所见,其中一个路径(自定义loadView方法)绕过了storyboard/NIB工作流程.请注意,如果您执行此过程,则您负责实例化UIView对象并设置view视图控制器的属性.另外,请不要调用super.loadView()您的实现.

例如,如果我想UILabel在视图中添加一堆对象,在Swift 3中你可以做类似的事情:

class DynamicViewController: UIViewController {

    var strings: [String]!

    override func loadView() {
        // super.loadView()   // DO NOT CALL SUPER

        view = UIView()
        view.backgroundColor = .lightGray

        let stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        view.addSubview(stackView)

        NSLayoutConstraint.activate([
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])

        for string in strings {
            let label = UILabel()
            label.translatesAutoresizingMaskIntoConstraints = false
            label.text = string
            stackView.addArrangedSubview(label)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样呈现它:

@IBAction func didTapButton(_ sender: AnyObject) {
    let controller = ViewController()
    controller.strings = ["Hello world", "Foobar", "Baz"]
    show(controller, sender: sender)
}
Run Code Online (Sandbox Code Playgroud)

(对于Swift 2再现,请参阅此答案的先前修订版.)


话虽如此,我不确定你为什么不关心不使用NIB或故事板.只需使用空白的.然后,您可以再次以编程方式动态地将控件添加到场景中,但请执行此操作viewDidLoad.它实现了与上面完全相同的效果,但避免使用相当陈旧的loadView技术,并且必须自己实例化和加载view属性.

  • @Munib - 您通常会调用“super”(本着 Liskov 替换原则的精神),除非文档明确建议您不要这样做。这是一个例子。异步“Operation”子类中的“start”方法是另一个。但是,您不想调用“super”的情况非常少见,而且他们非常擅长告诉您哪些地方不应该这样做。 (2认同)