无法在 Swift 中以编程方式创建 UIViewController



当我尝试在Swift中创建UIViewController的实例时,所有继承的初始化器都不可用,即使我没有在视图控制器(或其他任何东西,FWIW)中定义任何指定的初始化器。

此外,如果我尝试通过使其成为根视图控制器来显示它,它永远不会显示:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        window?.makeKeyAndVisible()
        window?.backgroundColor = UIColor.greenColor()

        let vc = ImageViewController()
        window?.rootViewController = vc
        return true
    }

视图控制器的代码只是 Xcode 的模板:

import UIKit
class ImageViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    /*
    // MARK: - Navigation
    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */
}

有人知道发生了什么????

正如你所指出的:只要 nib 名称与 objective-C 中的类名匹配,即使您在初始化视图控制器时没有指定 nib 名称,视图控制器仍将查找名称与视图控制器类名称匹配的 nib 文件。

但出于某种原因(也许这是一个错误),在 Swift 中并非如此。

而不是写:

let vc = ImageViewController()

初始化视图控制器时,必须显式指定接口:

let vc = ImageViewController(nibName: "nibName", bundle: nil)

为了方便起见,我想出了这个解决方法,这样我就不必在任何地方使用更长的初始值设定项。我有一个所有控制器都扩展的BaseViewController

init () {
    let className = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last
    super.init(nibName: className, bundle: NSBundle(forClass: self.dynamicType))
}
required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

请注意,使用 NSBundle(forClass: self.dynamicType) 可以处理不同目标中的命名空间。

然后当我想实例化一个ViewController时,我会像在Objective-C中一样使用MyViewController()

let Vc = UIViewController()
vc.view = yourview

或将上面的 vc 添加到 View 作为子视图控制器

configureChildViewController(vc,onView:yourview in Viewcontroller)

将此扩展用于 UiViewController

extension UIViewController {

func configureChildViewController(childController: UIViewController, onView: UIView?) {
    var holderView = self.view
    if let onView = onView {
        holderView = onView
    }
    addChildViewController(childController)
    holderView.addSubview(childController.view)
    constrainViewEqual(holderView, view: childController.view)
    childController.didMoveToParentViewController(self)
}
func scatterChildViewController(childController: UIViewController) {
    childController.willMoveToParentViewController(self)
    childController.view.removeFromSuperview()
    childController.removeFromParentViewController()
}
func constrainViewEqual(holderView: UIView, view: UIView) {
    view.translatesAutoresizingMaskIntoConstraints = false
    //pin 100 points from the top of the super
    let pinTop = NSLayoutConstraint(item: view, attribute: .Top, relatedBy: .Equal,
        toItem: holderView, attribute: .Top, multiplier: 1.0, constant: 0)
    let pinBottom = NSLayoutConstraint(item: view, attribute: .Bottom, relatedBy: .Equal,
        toItem: holderView, attribute: .Bottom, multiplier: 1.0, constant: 0)
    let pinLeft = NSLayoutConstraint(item: view, attribute: .Left, relatedBy: .Equal,
        toItem: holderView, attribute: .Left, multiplier: 1.0, constant: 0)
    let pinRight = NSLayoutConstraint(item: view, attribute: .Right, relatedBy: .Equal,
        toItem: holderView, attribute: .Right, multiplier: 1.0, constant: 0)
    holderView.addConstraints([pinTop, pinBottom, pinLeft, pinRight])
}

}

最新更新