Swift:自定义ViewController初始化程序

Bad*_*Cat 78 initialization objective-c uiviewcontroller ios swift

如何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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

override init(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder);
}
Run Code Online (Sandbox Code Playgroud)

如果我添加这个,Xcode会抱怨self.leftVC is not initialized at super.init call.所以我想这也不是解决方案.所以我想知道如何将自定义初始化器正确地添加到ViewControllerSwift中的子类中(因为在Objective-C中这看起来不是问题)?

Bad*_*Cat 107

解决了!一个人必须调用指定的初始化程序,在这种情况下是带有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()
}
Run Code Online (Sandbox Code Playgroud)

  • 摆脱那些丑陋的半冒号:) (31认同)
  • @SamSoffes所以你根本不使用(额外)空格?你将所有符号混淆为单个字符? (29认同)
  • 恕我直言,如果你键入一个字符,它不会影响编译的二进制文件,你不应该键入它:) (24认同)
  • 我喜欢分号.它们使代码变得不那么模糊,特别是那些可笑的Cocoa/Cocoa-Touch API名称和签名.来自Swift设计师的错误决定将他们删除恕我直言. (7认同)
  • 这个讨论让我想起了硅谷的标签与空格 (6认同)
  • 无论如何,代码都应自动缩进.此外,在这种情况下,分号是多余的,因为编译器和人都知道它是语句的结尾.摆脱分号可以通过摆脱冗余并直截了当地提供更清晰的代码. (3认同)

emr*_*tci 13

斯威夫特 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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • “您只能为可选属性编写自定义初始值设定项。” 是关键。我最初错过了。 (2认同)

wli*_*gke 11

不确定你是否设法完全解决这个问题......但是根据你想要你的类界面的外观以及你是否真的需要编码器功能,你也可以使用下面的代码:

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

由于init:leftVC:rightVC:gap是指定的初始化程序,您可以init:coder通过使其成为调用指定初始化程序的便捷初始化程序来满足实现的要求.

这可能比

override init(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder);
}
Run Code Online (Sandbox Code Playgroud)

因为如果你需要初始化一些属性,那么你需要重写它们.


Tr0*_*0yJ 11

对于更通用的UIViewController,您可以在Swift 2.0中使用它

init() {
    super.init(nibName: nil, bundle: nil)
}
Run Code Online (Sandbox Code Playgroud)