I'm creating a custom navigation controller. I have something like this:
我正在创建一个自定义导航控制器。我有这样的事情:
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
}
}
I wanted to test this out so I created a CustomNavigationController like this:
我想测试一下,所以我创建了一个CustomNavigationController,如下所示:
CustomNavigationController(rootViewController: ViewController())
When I run the app I get this:
当我运行应用程序时,我得到了这个:
fatal error: use of unimplemented initializer 'init(nibName:bundle:)' for class 'TestApp.CustomNavigationController'
I don't see the problem, can anyone help me out?
我没有看到问题,任何人都可以帮助我吗?
2 个解决方案
#1
13
UINavigationController
's implementation of init(rootViewController:)
probably calls self.init(nibName:bundle:)
which you haven't implemented so it throws the error.
UINavigationController的init(rootViewController :)实现可能会调用你没有实现的self.init(nibName:bundle :),因此它会抛出错误。
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.
除了已经覆盖的初始值设定项之外,还应覆盖init(nibName:bundle)。 init(nibName:bundle :)是指定的初始化程序,而init(rootViewController :)是一个便利初始化程序。
#2
14
While using custom navigation controller, we need to use override init
property of NavigationController
as-
使用自定义导航控制器时,我们需要使用NavigationController的覆盖initproperty-
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 -
&在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
}
}
As per Apple Document - To simplify the relationships between designated and convenience initializers, Swift applies the following three rules for delegation calls between initializers:
根据Apple文档 - 为了简化指定和便利初始化程序之间的关系,Swift对初始化程序之间的委托调用应用以下三个规则:
Rule 1 A designated initializer must call a designated initializer from its immediate superclass.
规则1指定的初始化程序必须从其直接超类中调用指定的初始化程序。
Rule 2 A convenience initializer must call another initializer from the same class.
规则2便捷初始化程序必须从同一个类调用另一个初始化程序。
Rule 3 A convenience initializer must ultimately call a designated initializer.
规则3便利初始化器必须最终调用指定的初始化器。
A simple way to remember this is:-
记住这一点的一个简单方法是: -
#1
13
UINavigationController
's implementation of init(rootViewController:)
probably calls self.init(nibName:bundle:)
which you haven't implemented so it throws the error.
UINavigationController的init(rootViewController :)实现可能会调用你没有实现的self.init(nibName:bundle :),因此它会抛出错误。
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.
除了已经覆盖的初始值设定项之外,还应覆盖init(nibName:bundle)。 init(nibName:bundle :)是指定的初始化程序,而init(rootViewController :)是一个便利初始化程序。
#2
14
While using custom navigation controller, we need to use override init
property of NavigationController
as-
使用自定义导航控制器时,我们需要使用NavigationController的覆盖initproperty-
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 -
&在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
}
}
As per Apple Document - To simplify the relationships between designated and convenience initializers, Swift applies the following three rules for delegation calls between initializers:
根据Apple文档 - 为了简化指定和便利初始化程序之间的关系,Swift对初始化程序之间的委托调用应用以下三个规则:
Rule 1 A designated initializer must call a designated initializer from its immediate superclass.
规则1指定的初始化程序必须从其直接超类中调用指定的初始化程序。
Rule 2 A convenience initializer must call another initializer from the same class.
规则2便捷初始化程序必须从同一个类调用另一个初始化程序。
Rule 3 A convenience initializer must ultimately call a designated initializer.
规则3便利初始化器必须最终调用指定的初始化器。
A simple way to remember this is:-
记住这一点的一个简单方法是: -