Search code examples
iosswiftuinavigationcontrollerinitializer

How to create custom UINavigationController class with custom init?


I tried to create a custom UINavigationController class as follows-

class NavigationController: UINavigationController {
    private let user: User

    init(user: User, rootViewController: UIViewController) {
        self.user = user
        super.init(rootViewController: rootViewController)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

The above code fails at runtime with the following error-

Fatal error: Use of unimplemented initializer 'init(nibName:bundle:)' for class 'app.NavigationController'

I tried to resolve the issue by adding the initializer

class NavigationController: UINavigationController {
    private let user: User

    init(user: User, rootViewController: UIViewController) {
        self.user = user
        super.init(rootViewController: rootViewController)
    }

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

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

The compiler throws the error "Property 'self.user' not initialized at super.init call".

Is there a way to solve this problem without making user property as implicitly unwrapped optional?


Solution

  • You can do the following :

    class NavigationController: UINavigationController {
        private let user: User
    
        init(user: User, rootViewController: UIViewController, nibName nibNameOrNil: String? = nil, bundle nibBundleOrNil: Bundle? = nil) {
            self.user = user
            super.init(nibName: nil, bundle: nil)
            self.viewControllers = [rootViewController]
        }
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    let vc = UIViewController()
    let nc = NavigationController(user: User(), rootViewController: vc)