Невозможно программно создать 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])
}
}