这与其他答案非常相似,但有一些解释。可接受的答案具有误导性,因为它的属性是可选的,并且没有暴露您init?(coder: NSCoder)
必须初始化每个属性的事实,唯一的解决方案是使用fatalError()
。最终,您可以通过将属性设置为可选属性来摆脱困境,但这并不能真正回答OP的问题。
// Think more of a OnlyNibOrProgrammatic_NOTStoryboardViewController
class ViewController: UIViewController {
let name: String
override func viewDidLoad() {
super.viewDidLoad()
}
// I don't have a nib. It's all through my code.
init(name: String) {
self.name = name
super.init(nibName: nil, bundle: nil)
}
// I have a nib. I'd like to use my nib and also initialze the `name` property
init(name: String, nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle? ) {
self.name = name
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
// when you do storyboard.instantiateViewController(withIdentifier: "ViewController")
// The SYSTEM will never call this!
// it wants to call the required initializer!
init?(name: String, coder aDecoder: NSCoder) {
self.name = "name"
super.init(coder: aDecoder)
}
// when you do storyboard.instantiateViewController(withIdentifier: "ViewController")
// The SYSTEM WILL call this!
// because this is its required initializer!
// but what are you going to do for your `name` property?!
// are you just going to do `self.name = "default Name" just to make it compile?!
// Since you can't do anything then it's just best to leave it as `fatalError()`
required init?(coder aDecoder: NSCoder) {
fatalError("I WILL NEVER instantiate through storyboard! It's impossible to initialize super.init?(coder aDecoder: NSCoder) with any other parameter")
}
}
基本上,您必须ABANDON从情节提要中加载它。为什么?
因为当你调用一个的viewController storyboard.instantiateViewController(withIdentifier: "viewController")
然后UIKit中会做它的事和呼叫
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
您永远不能将该调用重定向到另一个init方法。
的文件instantiateViewController(withIdentifier:)
:
使用此方法可以创建以编程方式显示的视图控制器对象。每次调用此方法时,它都会使用该init(coder:)
方法创建视图控制器的新实例。
但是,对于以编程方式创建的viewController或笔尖创建的viewControllers,您可以如上所述重定向该调用。