Swift调用instantiateViewController无法动态引用ViewController类名问题
问题根因
as!关键字后必须跟类型名称,你代码中的viewControllers是你提前声明的、用于存储控制器实例的变量,不是类型,因此编译器会抛出找不到对应类型的报错。- 你此前给
viewControllers赋值的写法也存在问题:直接写ViewController1是类本身,没有完成实例化,也和后续从Storyboard加载控制器的逻辑冲突。
解决方案
你不需要额外声明变量存储类信息,只要提前在Storyboard中给每个对应navigationid的控制器绑定好自定义类,从Storyboard加载出来的实例本身就会是对应子类的类型。你后续用到的backgroundColor、navigationItem、tabBarItem都是UIViewController的公共属性,不需要强转成具体子类也可以正常调用。
修正后的代码示例:
let tabBarController = CBFlashyTabBarController() tabBarController.viewControllers = filteredNavigation.map { arrayProperty -> UIViewController in var tabImage = "" // 根据导航名匹配对应图片 if arrayProperty.navname == "View1" { print("View1") tabImage = "tab1" } else if arrayProperty.navname == "View2" { print("View2") tabImage = "tab2" } // 直接从Storyboard加载控制器,不需要额外强转 let controller = storyboard!.instantiateViewController(withIdentifier: String(arrayProperty.navigationid)) controller.view.backgroundColor = .white controller.navigationItem.title = arrayProperty.navname controller.tabBarItem = UITabBarItem(title: arrayProperty.navname, image: #imageLiteral(resourceName: tabImage), tag: 0) // 如果需要给不同子类设置特有属性,可增加类型判断 if let vc1 = controller as? ViewController1 { // 设置ViewController1的独有属性 // vc1.customProperty = xxx } else if let vc2 = controller as? ViewController2 { // 设置ViewController2的独有属性 // vc2.anotherCustomProperty = xxx } controllerArray.append(controller) return controller }
注意事项
- 提前确认Storyboard中每个
navigationid对应的控制器,已经在身份检查器中绑定了对应的自定义类,否则加载出来的实例会是默认的UIViewController,子类强转会失败。 - 尽量不要用强制解包
storyboard!,可以增加可选绑定判断避免闪退。 - 你此前声明的全局
tabImage、viewControllers变量完全没必要,改成在闭包内声明局部变量即可,避免出现值错乱或者线程安全问题。
内容的提问来源于stack exchange,提问作者user17235974
相关产品推荐
相关产品推荐

