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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25527311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:04:13  来源:igfitidea点击:

Swift: Custom ViewController initializers

iosobjective-cswiftuiviewcontrollerinitialization

提问by BadmintonCat

How do you add custom initializers to UIViewControllersubclasses in Swift?

你如何UIViewController在 Swift 中为子类添加自定义初始值设定项?

I've created a sub class of UIViewControllerthat looks something like this:

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

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

        super.init();

        setupScrollView();
        setupViewControllers();
    }
}

When I run it I get a fatal error:

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

fatal error: use of unimplemented initializer 'init(nibName:bundle:)' for class 'MyApp.MyViewController'

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

I've read elewhere that when adding a custom initializer one has to also override init(coder aDecoder:NSCoder)so let's override that initand see what happens:

我已经在 elewhere 中读到,当添加自定义初始值设定项时,还必须覆盖,init(coder aDecoder:NSCoder)所以让我们覆盖它init,看看会发生什么:

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

If I add this, Xcode complains that self.leftVC is not initialized at super.init call. So I guess that can't be the solution either. So I wonder how can I add custom initializers properly to a ViewControllersubclass in Swift (since in Objective-C this seems not to be a problem)?

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

回答by BadmintonCat

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

解决了!必须调用指定的初始化程序,在这种情况下是带有 nibName 的初始化程序,显然……

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

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

    setupScrollView()
    setupViewControllers()
}

回答by Tr0yJ

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

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

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

回答by wlingke

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:gapis a designated initializer, you can fulfill the requirement of implementing init:coderby making it a convenience initializer that calls your designated initializer.

由于init:leftVC:rightVC:gap是指定构造器,您可以init:coder通过将其设置为调用指定构造器的便利构造器来满足实现的要求。

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.

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

回答by emrcftci

Swift 5

斯威夫特 5

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

如果你想编写自定义初始化器UIViewController,初始化为storyBoard.instantiateViewController(withIdentifier: "ViewControllerIdentifier")

You can write custom initializer for only Optionalproperties.

您可以仅为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
    }
}