【问题标题】:How to create custom UINavigationController class with custom init?如何使用自定义初始化创建自定义 UINavigationController 类?
【发布时间】:2019-11-28 05:23:30
【问题描述】:

我尝试创建一个自定义的UINavigationController 类如下-

class NavigationController: UINavigationController {
    private let user: User

    init(user: User, rootViewController: UIViewController) {
        self.user = user
        super.init(rootViewController: rootViewController)
    }

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

上述代码在运行时失败并出现以下错误-

致命错误:对“app.NavigationController”类使用未实现的初始化程序“init(nibName:bundle:)”

我尝试通过添加初始化程序来解决问题

class NavigationController: UINavigationController {
    private let user: User

    init(user: User, rootViewController: UIViewController) {
        self.user = user
        super.init(rootViewController: rootViewController)
    }

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

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

编译器抛出错误“Property 'self.user' not initialized at super.init call”。

有没有办法在不将 user 属性设置为隐式解包可选的情况下解决此问题?

【问题讨论】:

    标签: ios swift uinavigationcontroller initializer


    【解决方案1】:

    您可以执行以下操作:

    class NavigationController: UINavigationController {
        private let user: User
    
        init(user: User, rootViewController: UIViewController, nibName nibNameOrNil: String? = nil, bundle nibBundleOrNil: Bundle? = nil) {
            self.user = user
            super.init(nibName: nil, bundle: nil)
            self.viewControllers = [rootViewController]
        }
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    let vc = UIViewController()
    let nc = NavigationController(user: User(), rootViewController: vc)
    

    【讨论】:

      【解决方案2】:

      使用带有自定义参数的便捷初始化并调用指定的初始化程序来设置根视图控制器

      final class NavigationController: UINavigationController {
          
          private var user: User?
          
          convenience init(rootViewController: UIViewController, user: User) {
              self.init(rootViewController: rootViewController)
              self.user = user
          }
          
          override init(rootViewController: UIViewController) {
              super.init(rootViewController: rootViewController)
          }
      
          required init?(coder aDecoder: NSCoder) {
              fatalError("init(coder:) has not been implemented")
          }
      }
      
      /// How to use
      
      let user = User()
      let rootViewController = UIViewController()
      let navigationController = NavigationController(rootViewController: rootViewController, user: user) 
      

      【讨论】:

        【解决方案3】:

        方法

        override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)
        

        是指定的初始化器,这意味着它将始终被调用,而

        init(rootViewController: )
        

        是一个方便的初始化器,出于方便的原因可能会被调用。当指定的初始化程序被调用时,您的类有一个未初始化的用户常量。您可以将 user 切换为可选 var 并将其初始化为 nil。

        【讨论】:

          【解决方案4】:

          不要像这样初始化用户。 在 Controller 中,您将其称为 NavigationController

          • private let user : User 更改为

            var user : User!

          • 初始化您的 NavigationController

          • 然后像这样设置用户:

            navigationController.user = self.user

          self.user 是您要提供给navigationController变量

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-11-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多