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

Как написать методы init UIViewController в Swift

Я не могу добавить метод init к следующему классу UIViewController. Мне нужно написать код в методе init. Должен ли я писать метод init (coder)? Даже когда я добавляю методы кодера и декодера, я все равно получаю ошибки. Я также попытался использовать метод 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 и bundle, тогда ошибка "Требуется инициализатор инициализации (кодера)".

Даже когда я добавляю init (coder) и init (декодер), он не работает.

4b9b3361

Ответ 1

Я использовал:

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

Некоторые люди предложили:

convenience init(){
    self.init()
}

Но это дает вам бесконечный цикл.

Ответ 2

Все эти ответы являются полу ответами. Некоторые люди испытывают бесконечные циклы в связанных сообщениях, потому что они только добавляют convenience init() (он рекурсивно вызывает себя, если вы не предоставляете отдельный метод init() для его вызова), в то время как другие люди пренебрегают расширением суперкласса, Этот формат объединяет все решения, чтобы полностью удовлетворить проблему.

// 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 answer
}

Изменить: Кроме того, если вы хотите инициализировать любые свойства класса с помощью параметров, переданных в ваш метод convenience init(), без использования всех переопределенных методов init(), вы можете установить все эти свойства как неявно развернутые варианты, которые являются образцом используемым самими Apple.

Ответ 3

Вам необходимо переопределить инициализатор 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:"))
    }
...
...
}

Кроме того, при вызове инициализатора суперкласса убедитесь, что вы не просто передали nil для nibName и bundle. Вы должны отказаться от всего, что было передано.


Обратите внимание, что "удобный метод инициализации", упомянутый в некоторых ответах, имеет значение только в том случае, если вы на самом деле "вручную" сами инициализируете контроллер представления. (Есть очень немного ситуаций, когда вы могли бы сделать это.) Если вы хотите "сделать что-то во время обычной инициализации" - например, создать распознаватель жестов или просто инициализировать некоторые переменные - единственно возможное решение - это точно тот, который дан в этом ответе.

Ответ 4

Вместо этого вы можете просто создать инициализатор удобства, инициализаторы удобства не переопределяют init(), а просто называют его упростить процесс.

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

Ответ 5

Думаю, вам нужно добавить

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

Надеюсь, что это поможет

Ответ 6

Я столкнулся с этим вопросом о тебе, который просил долгий путь назад. Но никто не дал основополагающего ответа на этот вопрос. Это основной в Swift, который: - Подкласс должен инициализировать свои переменные перед завершением инициализации суперкласса.

Следовательно, как 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:")))
 }}