在 Swift 中动态创建 uiviewcontroller

Posted

技术标签:

【中文标题】在 Swift 中动态创建 uiviewcontroller【英文标题】:Creating uiviewcontroller dynamically in Swift 【发布时间】:2016-06-22 08:07:08 【问题描述】:

我想在不创建类或使用 Mainstoryboard 的情况下动态创建 UIViewController。我希望它以编程方式发生。这可能吗? 我想根据动态数据创建 UIViewControllers。

【问题讨论】:

let viewController = UIViewController() =) 请更好地解释并向我们展示您在代码中的尝试,以获得更深入的答案 好的。我会试试这个 【参考方案1】:

是的,您可以通过编程方式动态创建视图。我知道你说过你不想使用课程,但你真的必须这样做。不过,关键是您不必让此类对 UI 进行硬编码,而是动态构建它。

因此,您可以继承 UIViewController,但将动态构建视图所需的数据传递给它,然后实现 loadView 方法来执行此操作。不需要笔尖或故事板场景。只需创建view 并根据您的动态数据构建子视图。这在旧版View Controller Programming Guide 中进行了描述。 (请注意,该文档的某些部分不再适用,尤其是所有“卸载”视图讨论。但它确实描述并说明了loadView 过程,它仍然可以正常工作。)

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

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

例如,如果我只想将一堆 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)
        
    

你可以这样展示它:

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

(对于 Swift 2 版本,请参阅 previous revision of this answer。)


说了这么多,我不知道您为什么担心不使用 NIB 或情节提要。只用一个空白的。然后,您可以再次以编程方式将控件动态添加到场景中,但在viewDidLoad 中进行。它实现了与上述完全相同的效果,但避免了使用相当陈旧的loadView 技术,并且不必自己实例化和加载view 属性。

【讨论】:

谢谢你这么详细的回答,只是一个问题,我们是否也需要避免在任何其他被覆盖的方法中调用 super ?比如viewDidAppear? @Munib - 您通常调用super(本着 Liskov 替换原则的精神),除非文档明确建议您不要这样做。这是一个例子。异步Operation 子类中的start 方法是另一个。但你不想打电话给super 的情况很少见,而且他们很会告诉你哪些地方不应该这样做。 let controller = ViewController() 应改为:let controller = DynamicViewController() @Dan 谢谢。固定。

以上是关于在 Swift 中动态创建 uiviewcontroller的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中动态创建 uiviewcontroller

游戏中心登录 Swift

如何在 Swift 中动态创建 buttonAction 函数

如何在swift中的动态表视图中创建动态表视图?

如何动态创建控件并在swift 4中动态对齐?

动态创建的 swift 3/xcode 标签中的行距