0

I have a UINavigationController subclass:

fileprivate class NavController: UINavigationController {

  override init(navigationBarClass: AnyClass?, toolbarClass: AnyClass?) {
    super.init(navigationBarClass: navigationBarClass, toolbarClass: toolbarClass)
    ...
  }

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

  ...
}

I instantiate this class as:

navController = NavController(navigationBarClass: nil, toolbarClass: nil)

This compiles, but fails at runtime:

AppDelegate.swift: 87: 19: fatal error: use of unimplemented initializer 'init(nibName:bundle:)' for class 'NavController'

I don't understand why init(nibName:bundle:) is being called, when I specified the keywords navigationBarClass: and toolbarClass:.

If I delete all the initialisers from my subclass, it works fine, which is confusing since overriding a method / initialiser that only calls super should be a noop.

Line 87 is the one where the class is declared. I tried stepping in with a debugger, but I can't step into UIKit code, only my code.

In case this matters, this is on iOS 10 and Swift 3.

Kartick Vaddadi
  • 4,818
  • 6
  • 39
  • 55

1 Answers1

1

The issue stems from the life cycle of the UINavigationController, because if you print the functions when overriding all the inits the console looks like this:

init(nibName:bundle:)
init(navigationBarClass:toolbarClass:)

So you also have to override the init(nibName:bundle:) as it is called first, like this:

class NavController: UINavigationController {

    /* Properties */

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

    override init(navigationBarClass: AnyClass?, toolbarClass: AnyClass?) {
        super.init(navigationBarClass: navigationBarClass, toolbarClass: toolbarClass)
    }

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

}

extension NavController {
    /* Methods */
}
Harry Wright
  • 306
  • 2
  • 7
  • Im not sure, placing that code in a current project works fine with no issues, being implemented `let navController = NavController(navigationBarClass: nil, toolbarClass: nil)` – Harry Wright Mar 07 '17 at 11:06
  • This works, though it's a mystery why — overriding something to just call super should be a noop. – Kartick Vaddadi Mar 07 '17 at 11:11
  • Its just swift being swift, loves to annoy us all – Harry Wright Mar 07 '17 at 11:15
  • Not sure if I can ask a continuous question here. Once after initializing the custom nav bar. How to access that navigation bar that gives my custom type? I apologize if it is a new question. – coolly Aug 12 '17 at 06:58