Неустранимая ошибка: использование нереализованного инициализатора в настраиваемом диспетчере навигации

Я создаю настраиваемый контроллер навигации. У меня есть что-то вроде этого:

public class CustomNavigationController: UINavigationController {

    // MARK: - Life Cycle

    override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)

        delegate = self
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        delegate = self
    }
}

Я хотел проверить это, поэтому создал CustomNavigationController следующим образом:

CustomNavigationController(rootViewController: ViewController())

Когда я запускаю приложение, я получаю следующее:

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

Я не вижу проблемы, может ли кто-нибудь помочь мне?

Ответ 1

UINavigationController реализация init(rootViewController:) вероятно, вызывает self.init(nibName:bundle:) который вы не реализовали, поэтому он выдает ошибку.

Вы должны переопределить init(nibName:bundle) в дополнение к инициализаторам, которые вы уже переопределили. init(nibName:bundle:) - назначенный инициализатор, в то время как init(rootViewController:) - инициализатор удобства.

Ответ 2

При использовании настраиваемого контроллера навигации нам нужно использовать свойство override init для NavigationController as-

class CustomNavigationController: UINavigationController {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

    }
    override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)
    }
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

}

& в классе Appdelegate -

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        self.window = UIWindow(frame: UIScreen.main.bounds)
        let vc = ViewController(nibName: "ViewController", bundle: nil)
        let navi =  CustomNavigationController(rootViewController: vc)
        window?.backgroundColor = .white
        window?.rootViewController = navi
        window?.makeKeyAndVisible()
        return true
    }
}

Согласно Apple Document. Для упрощения отношений между назначенными и удобными инициализаторами Swift применяет следующие три правила для делегирования вызовов между инициализаторами:

Правило 1 Назначенный инициализатор должен вызывать назначенный инициализатор из своего непосредственного суперкласса.

Правило 2 Инициализатор удобства должен вызывать другой инициализатор из того же класса.

Правило 3 Инициализатор удобства должен в конечном итоге вызвать назначенный инициализатор.

Простой способ запомнить это:

enter image description here