Swift:自定义ViewController初始化程序


87

如何UIViewController在Swift的子类中添加自定义初始化程序?

我创建了一个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 :)”

我读过elewhere,添加自定义初始化程序时还必须覆盖它,init(coder aDecoder:NSCoder)所以让我们覆盖它init,看看会发生什么:

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

如果添加此代码,Xcode会抱怨self.leftVC is not initialized at super.init call。所以我想那也不是解决方案。所以我想知道如何ViewController在Swift中的子类中正确添加自定义初始化程序(因为在Objective-C中这似乎不是问题)?


您如何尝试实例化您的MyViewController
2014年

为什么不实例化viewDidLoad()中的所有内容,您可以按照自己的方式初始化它们
tudoricc 2014年

@MikePollard具有dualViewCtrl = DualViewCtrl(leftVC:l,rightVC:r,gap:50)...我已经发现我需要使用initWithNib初始化程序。
BadmintonCat

3
@tudoricc因为经常需要实例属性,这些实例属性在初始化程序中使用给定的参数安全地初始化。您无法在viewDidLoad中执行此操作,因为那样一来,就无法保证需要时属性可用。
BadmintonCat

很抱歉,我只是将viewDidLoad()视为初始化程序。thanx的解释
tudoricc

Answers:


122

解决了!必须调用指定的初始化程序,在这种情况下,该初始化程序是使用nibName的init,显然...

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

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

    setupScrollView()
    setupViewControllers()
}

31
摆脱那些丑陋的半冒号:)
MobileMon

8
我喜欢分号。它们使代码的模棱两可性降低,尤其是那些冗长的Cocoa / Cocoa-Touch API名称和签名。Swift设计师的错误决定是将其删除恕我直言。
BadmintonCat 2015年

25
恕我直言,如果您键入一个字符并且它不会影响已编译的二进制文件,则不应键入它:)
Sam Soffes 2015年

32
@SamSoffes,所以您根本不使用(额外)空格吗?您将所有符号混淆为单个字符吗?
Victor Jalencas 2015年

8
这次讨论让我想起了硅谷的制表符与空格
亚伦

13

对于更通用的UIViewController,您可以从Swift 2.0开始使用

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

11

不确定是否能够完全解决此问题...但是根据您希望类界面的外观以及是否实际需要编码器功能,也可以使用以下代码:

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

由于init:leftVC:rightVC:gap是指定的初始值设定项,因此可以满足实现的要求init:coder通过将其用作调用您指定的初始值设定项的便捷初始值设定项。

这可能比

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

因为如果您需要初始化某些属性,则需要重写它们。


8

迅捷5

如果要编写使用初始化的自定义初始化UIViewController程序storyBoard.instantiateViewController(withIdentifier: "ViewControllerIdentifier")

您只能为Optional属性编写自定义初始化程序。

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
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.