我正在以编程方式实现我的UITabBarController,尝试从Bundle.main.infoDictionary检索控制器时出错!["CFBundleExecutable"]
以下是 UITabBarController 的代码:
import UIKit
class ENTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
addChildViewControllers()
}
fileprivate func addChildViewControllers() {
addChildViewController("ENSwipeViewController", imageName: "TabBar_swipe_")
addChildViewController("ENSocialViewController", imageName: "TabBar_social_")
addChildViewController("ENNotificationViewController", imageName: "TabBar_notification_")
}
fileprivate func addChildViewController(_ childControllerName: String, imageName: String) {
let ns = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String
let cls: AnyClass? = NSClassFromString(ns + "." + childControllerName)
let vcClass = cls as! UIViewController.Type
let vc = vcClass.init()
vc.tabBarItem.image = UIImage(named: imageName)
vc.tabBarItem.selectedImage = UIImage(named: imageName + "selected")
let nav = UINavigationController()
nav.addChildViewController(vc)
addChildViewController(nav)
}
}
错误发生在let vcClass = cls as! UIViewController.Type
,并且是:
线程 1:致命错误:解开包装时意外发现 nil 可选值
以下是ENSwipeViewController的简单代码:
import UIKit
class ENSwipeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
}
}
好吧,如果您查看文档,您会发现它说:
返回值
由 aClassName 命名的类对象,如果没有该名称命名的类,则为 nil 当前已加载。如果 aClassName 为 nil,则返回 nil。
因此,由于您的ENSwipeViewController
尚未加载,因此返回 nil...
您的错误是由于尝试强制解开可选值 cls
的包装引起的。类型是 AnyObject.type 因此,将以下代码行添加到您的 func 将解决您的问题。
addChildViewController
let vcClassArray: [UIViewController.Type] = [
ENSwipeViewController.self
]
let vcClass = classArray[0] // we only have one value
// if you have more you could simply make this a variable
let vc = vcClass.init()
上面的这些行替换了您在同一函数中的内容。
let vcClass = cls as! UIViewController.Type
let vc = vcClass.init()
您需要将AnyClass?
转换为您要访问的类,并使用vcClass.init()
init