致命错误:在自定义navigationcontroller中使用未实现的初始化程序

时间:2016-07-12 16:47:24

标签: ios swift2

我正在创建一个自定义导航控制器。我有这样的事情:

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'

我没有看到问题,任何人都可以帮助我吗?

3 个答案:

答案 0 :(得分:21)

UINavigationController init(rootViewController:)的实施可能会调用您尚未实施的self.init(nibName:bundle:),因此会引发错误。

除了您已覆盖的初始值设定项之外,您还应覆盖init(nibName:bundle)init(nibName:bundle:)是指定的初始化程序,而init(rootViewController:)是便捷初始化程序。

答案 1 :(得分:19)

使用自定义导航控制器时,我们需要使用override init NavigationController属性 作为 -

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文件 - 为了简化指定和便利初始化程序之间的关系,Swift对初始化程序之间的委托调用应用以下三个规则:

  

规则1指定的初始化程序必须调用指定的初始化程序   来自其直接的超类。

     

规则2便捷初始化程序必须从中调用另一个初始化程序   同一个班级。

     

规则3便利初始化程序必须最终调用指定的   初始化程序。

     

记住这一点的一个简单方法是: -

enter image description here

答案 2 :(得分:4)

我在iOS 12.4上的用户中遇到了此问题,因此要在自定义初始化程序中解决此问题,我做了如下操作:

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

对于13以下的每个iOS版本,我基本上都以不同的方式初始化类,这似乎是最短的解决方案。