如何在Swift中编写UIViewController的init方法

我无法将init方法添加到以下UIViewController类。 我需要在init方法中编写一些代码。 我必须编写init(编码器)方法吗? 即使当我添加编码器和解码器的方法,我仍然得到错误。 我也尝试使用init方法,但没有任何参数,但似乎也没有工作。

class ViewController: UIViewController { var tap: UITapGestureRecognizer? override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nil, bundle: nil) tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } ... ... } 

如果我没有参数调用super.init()方法的错误是“必须调用超类的指定初始化”,如果我传递参数nib和捆绑,那么错误是“必需的初始化init(编码器)”。

即使当我添加init(编码器)和init(解码器),它不起作用。

我用了:

 convenience init() { self.init(nibName:nil, bundle:nil) } 

有人build议:

 convenience init(){ self.init() } 

但是这给你一个无限循环。

您需要重写init(nibName:bundle:)初始化程序, 提供init(coder:)所需的初始化程序,并在其中初始化tap

 class ViewController: UIViewController { var tap: UITapGestureRecognizer? override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { print("init nibName style") super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } // note slightly new syntax for 2017 required init?(coder aDecoder: NSCoder) { print("init coder style") super.init(coder: aDecoder) tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } ... ... } 

另外,请确保在调用超类初始化程序时,您不只是将nibName传递给nibNamebundle 。 你应该放弃通过的任何东西。

所有这些答案都是一半的答案。 有些人在相关文章中遇到了无限循环,因为他们只是增加了convenience init() (如果你不提供一个独特的init()方法来调用它,它会recursion地调用自己),而其他人则忽略扩展超类。 这种格式结合了所有的解决scheme来完全解决问题。

 // This allows you to initialise your custom UIViewController without a nib or bundle. convenience init() { self.init(nibName:nil, bundle:nil) } // This extends the superclass. override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } // This is also necessary when extending the superclass. required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") // or see Roman Sausarnes's answer } 

编辑:另外,如果你想使用传递给你convenience init()方法的参数来初始化任何类的属性,而没有重写的init()方法的抱怨,那么你可以将所有这些属性设置为隐式解包的optionals, 苹果自己 。

您可以创build一个方便的初始化器,而方便初始化器不会覆盖init(),而只是简单地调用它。

 class ViewController: UIViewController { var tap: UITapGestureRecognizer? convenience init(){ self.init() tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } } 

我想你必须补充

 required init(coder aDecoder: NSCoder) { print("init coder") super.init(coder: aDecoder) } 

要么

 convenience init() { self.init() } 

你也必须写init。 不要删除它

 var tap: UITapGestureRecognizer? override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nil, bundle: nil) } 

希望能帮助到你

我碰到这个问题,你问了很久回来。 但是没有人提供这个问题的基本答案。 在Swift中这是一个基本的东西: – 子类必须在它的超类初始化完成之前初始化它的variables。

因此,正如Ankit Goel提到的崩溃:“必须调用超类的指定初始值”

因此更新的代码将是: –

 class ViewController: UIViewController { var tap: UITapGestureRecognizer? override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { print("init nibName style") self.tap = nil super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) self.tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:"))) } required init?(coder aDecoder: NSCoder) { print("init coder style") self.tap = nil super.init(coder: aDecoder) tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:"))) }}