Fatal error: use of unimplemented initializer in custom navigationcontroller

后端 未结 3 486
情话喂你
情话喂你 2020-12-29 19:49

I\'m creating a custom navigation controller. I have something like this:

public class CustomNavigationController: UINavigationController {

    // MARK: - L         


        
相关标签:
3条回答
  • 2020-12-29 20:11

    UINavigationController's implementation of init(rootViewController:) probably calls self.init(nibName:bundle:) which you haven't implemented so it throws the error.

    You should override init(nibName:bundle) in addition to the initializers you already override. init(nibName:bundle:) is a designated initializer while init(rootViewController:) is a convenience initializer.

    0 讨论(0)
  • 2020-12-29 20:24

    I had this issue happen to users on iOS 12.4, so to do a workaround in my custom initializer I did something like this:

    init(rootViewController: UIViewController, numberOfPages: Int) {
        self.numberOfPages = numberOfPages
        if #available(iOS 13.0, *) {
            super.init(rootViewController: rootViewController)
        } else {
            super.init(nibName: nil, bundle: nil)
            self.viewControllers = [rootViewController]
        }
    }
    

    I basically initialize my class differently for every iOS version below 13. This does seem like the shortest solution.

    0 讨论(0)
  • 2020-12-29 20:27

    While using custom navigation controller, we need to use override initproperty of 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)
        }
    
    }
    

    & in Appdelegate class use -

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

    As per Apple Document - To simplify the relationships between designated and convenience initializers, Swift applies the following three rules for delegation calls between initializers:

    Rule 1 A designated initializer must call a designated initializer from its immediate superclass.

    Rule 2 A convenience initializer must call another initializer from the same class.

    Rule 3 A convenience initializer must ultimately call a designated initializer.

    A simple way to remember this is:-

    0 讨论(0)
提交回复
热议问题