Swift: 自定义 ViewController 初始值设定项

如何在 Swift 中向 UIViewController子类添加自定义初始化器?

我已经创建了 UIViewController的一个子类,它看起来像这样:

class MyViewController : UIViewController
{
init(leftVC:UIViewController, rightVC:UIViewController, gap:Int)
{
self.leftVC = leftVC;
self.rightVC = rightVC;
self.gap = gap;


super.init();


setupScrollView();
setupViewControllers();
}
}

当我运行它时,我得到一个致命的错误:

致命错误: 对类‘ MyApp.MyViewController’使用未实现的初始化器‘ init (nibName: bundle:)’

我在其他地方读到过,当添加一个自定义初始化程序时,必须覆盖 init(coder aDecoder:NSCoder),所以让我们覆盖 init,看看会发生什么:

override init(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder);
}

如果我添加这个,Xcode 会抱怨 self.leftVC is not initialized at super.init call。所以我想这也不是解决办法。因此,我想知道如何在 Swift 中正确地将自定义初始化器添加到 ViewController子类(因为在 Objective-C 中这似乎不是一个问题) ?

70111 次浏览

Solved it! One has to call the designated initializer which in this case is the init with nibName, obviously ...

init(leftVC:UIViewController, rightVC:UIViewController, gap:Int)
{
self.leftVC = leftVC
self.rightVC = rightVC
self.gap = gap


super.init(nibName: nil, bundle: nil)


setupScrollView()
setupViewControllers()
}

Not sure if you managed to fully solve this... but depending on how you want your class's interface to look and whether or not you actually need the coder functionality, you can also use the below:

convenience required init(coder aDecoder: NSCoder)
{
//set some defaults for leftVC, rightVC, and gap
self.init(leftVC, rightVC, gap)
}

Since init:leftVC:rightVC:gap is a designated initializer, you can fulfill the requirement of implementing init:coder by making it a convenience initializer that calls your designated initializer.

This could be better than

override init(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder);
}

because if you need to initialize some properties, then you would need to rewrite them.

For a more generic UIViewController you can use this as of Swift 2.0

init() {
super.init(nibName: nil, bundle: nil)
}

Swift 5

If you want to write custom initializer to UIViewController which is initialized with storyBoard.instantiateViewController(withIdentifier: "ViewControllerIdentifier")

You can write custom initializer for only Optional properties.

class MyFooClass: UIViewController {
var foo: Foo?


init(with foo: Foo) {
self.foo = foo
super.init(nibName: nil, bundle: nil)
}


public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.foo = nil
}
}