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

use*_*522 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
    }
}
Run Code Online (Sandbox Code Playgroud)

我想测试一下,所以我创建了一个这样的CustomNavigationController:

CustomNavigationController(rootViewController: ViewController())
Run Code Online (Sandbox Code Playgroud)

当我运行应用程序时,我得到了这个:

fatal error: use of unimplemented initializer 'init(nibName:bundle:)' for class 'TestApp.CustomNavigationController'
Run Code Online (Sandbox Code Playgroud)

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

dan*_*dan 27

UINavigationController的实施init(rootViewController:)可能要求self.init(nibName:bundle:)您还没有实现,因此引发错误.

init(nibName:bundle)除了已经覆盖的初始值设定项之外,您还应该覆盖它们. init(nibName:bundle:)是一个指定的初始化程序,init(rootViewController:)而是一个便利初始化程序.

  • init(rootViewController:) 不能是方便的初始化程序。正如初始化器委托规则中所述(在下面@Jack的回答中列出),指定的初始化器只能调用另一个指定的初始化器。如果您尝试从指定的子类初始值设定项调用超类便利初始值设定项,则应该是编译器错误。 (3认同)
  • 这个崩溃是iOS12用户突然出现的。尽管空初始化程序没有任何意义,但它修复了该崩溃。 (2认同)

Jac*_*ack 23

使用自定义导航控制器时,我们需要使用 as- 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)
    }

}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

根据Apple文档 - 为了简化指定和便利初始化程序之间的关系,Swift对初始化程序之间的委派调用应用以下三个规则:

规则1指定的初始化程序必须从其直接超类中调用指定的初始化程序.

规则2便捷初始化程序必须从同一个类调用另一个初始化程序.

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

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

在此输入图像描述


Rep*_*ose 10

我在 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]
    }
}
Run Code Online (Sandbox Code Playgroud)

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