Невозможно программно создать UIViewController в Swift

Когда я пытаюсь создать экземпляр UIViewController в Swift, все унаследованные инициализаторы недоступны, хотя я не определял какие-либо назначенные в контроллере представления (или что-то еще, 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.
    }
    */

}

Кто-нибудь знает, что происходит????

Ответ 1

Как вы указали: до тех пор, пока имя nib совпадает с именем класса в objective-C, даже если вы не укажете имя ниба при инициализации контроллера вида, контроллер вида будет найдите файл nib, имя которого совпадает с именем класса контроллера вида.

Но по какой-то причине (возможно, это ошибка), это не так в Swift.

Вместо записи:

let vc = ImageViewController()

Вы должны явно указать интерфейс при инициализации контроллера вида:

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

Ответ 2

В качестве удобства я придумал это обходное решение, так что мне не нужно использовать более длинный инициализатор повсюду. У меня есть 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, я использую MyViewController(), как вы могли бы в Objective-C.

Ответ 3

let Vc = UIViewController()
vc.view = yourview

или добавить выше vc для просмотра как ChildviewController

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])
}

}