Подтвердить что ты не робот

Swift: пользовательские инициализаторы ViewController

Как добавить пользовательские инициализаторы в подклассы 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();
    }
}

Когда я запускаю его, я получаю фатальную ошибку:

фатальная ошибка: использование нереализованного инициализатора 'init (nibName: bundle:)' для класса 'MyApp.MyViewController'

Я читал 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 это, похоже, не проблема)?

4b9b3361

Ответ 1

Решил! Нужно вызвать назначенный инициализатор, который в этом случае является init с 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()
}

Ответ 2

Не уверен, что вам удалось полностью решить эту проблему... но в зависимости от того, как вы хотите, чтобы интерфейс вашего класса выглядел, и действительно ли вам нужна функциональность кодера, вы также можете использовать ниже:

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);
}

потому что если вам нужно инициализировать некоторые свойства, вам нужно будет их переписать.

Ответ 3

Для более общего UIViewController вы можете использовать это как Swift 2.0

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

Ответ 4

Swift 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
    }
}