简体   繁体   English

在 Swift 中动态创建 uiviewcontroller

[英]Creating uiviewcontroller dynamically in Swift

I want to create UIViewController dynamically without creating a class or using Mainstoryboard.I want it to happen programatically.Is it possible?我想在不创建类或使用 Mainstoryboard 的情况下动态创建 UIViewController。我希望它以编程方式发生。这可能吗? I want to create UIViewControllers depending on the dynamic data.我想根据动态数据创建 UIViewControllers。

Yes, you can create a view dynamically, programmatically.是的,您可以以编程方式动态创建视图。 I know you said you don't want to use a class, but you really have to.我知道你说过你不想使用类,但你真的必须这样做。 The key, though, is that you don't have to have this class hard code the UI, but rather build it dynamically.不过,关键是您不必让此类对 UI 进行硬编码,而是动态构建它。

So, you can subclass UIViewController , but pass it the data it needs to build the view dynamically and then implement the loadView method to do so.因此,您可以UIViewController ,但将动态构建视图所需的数据传递给它,然后实现loadView方法来执行此操作。 No NIB or storyboard scene is needed.不需要 NIB 或故事板场景。 Just create the view and build the subviews based upon your dynamic data.只需根据您的动态数据创建view并构建子视图。 This is described in the legacy View Controller Programming Guide .这在旧版视图控制器编程指南中有所描述。 (Please note that portions of that document no longer apply, notably al of the "unload" view discussion. But it does describe and illustrate the loadView process, which still works fine.) (请注意,该文档的部分内容不再适用,特别是所有“卸载”视图讨论。但它确实描述和说明了loadView过程,该过程仍然可以正常工作。)

The process for building a view for a view controller is as follows:为视图控制器构建视图的过程如下:

在此处输入图片说明

As you can see, one of the paths (the custom loadView method) bypasses the storyboard/NIB workflow.如您所见,其中一个路径(自定义loadView方法)绕过了情节提要/NIB 工作流。 Note, if you go about this process, you are responsible for instantiating a UIView object and setting the view property of the view controller.请注意,如果您执行此过程,您将负责实例化UIView对象并设置视图控制器的view属性。 Also, do not call super.loadView() in your implementation.另外,不要super.loadView()在您的实现。

For example, if I wanted to just add a bunch of UILabel objects to the view, in Swift 3 you could do something like:例如,如果我只想向视图添加一堆UILabel对象,在 Swift 3 中,您可以执行以下操作:

class ViewController: 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)
        }
    }
}

And you could present it like so:你可以像这样呈现它:

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

(For Swift 2 renditions, see previous revision of this answer .) (对于 Swift 2 版本,请参阅此答案的先前修订版。)


Having said this, I'm not sure why you're concerned about not using a NIB or storyboard.话虽如此,我不确定您为什么担心不使用 NIB 或故事板。 Just use a blank one.只用一个空白的。 And then, you can again programmatically add your controls to the scene dynamically, but do it in viewDidLoad .然后,您可以再次以编程方式将控件动态添加到场景中,但在viewDidLoad It achieves the exact same effect as the above, but avoids using the fairly antiquated loadView technique and from having to instantiate and load the view property yourself.它实现了与上述完全相同的效果,但避免了使用相当陈旧的loadView技术,也避免了必须自己实例化和加载view属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM