Swift中函数传入UIViewController类型时提示找不到类型的解决方案
Swift 实现传入ViewController类型的页面切换函数问题解决
你想要实现一个可传入UIViewController类型的页面切换函数,编写的代码如下:
extension UIViewController { func switchScreen(storyboardName:String,viewControllerName:String,vcc:UIViewController) { let mainStoryboard = UIStoryboard(name: storyboardName, bundle: Bundle.main) if let viewController = mainStoryboard.instantiateViewController(withIdentifier: viewControllerName) as? vcc { self.present(viewController, animated: true, completion: nil) } } }
Xcode返回错误提示:Cannot find type 'vcc' in scope,即使给参数添加.Type仍无法解决,问题出在类型与实例的混淆以及类型转换的写法错误,以下是两种可行的解决方式:
方案一:泛型约束实现
通过泛型明确要转换的ViewController类型,代码更简洁且类型安全:
extension UIViewController { func switchScreen<T: UIViewController>(storyboardName: String, viewControllerName: String, targetType: T.Type) { let mainStoryboard = UIStoryboard(name: storyboardName, bundle: Bundle.main) // 利用泛型T做类型转换 if let viewController = mainStoryboard.instantiateViewController(withIdentifier: viewControllerName) as? T { self.present(viewController, animated: true, completion: nil) } } }
调用示例:
// 传入目标ViewController的类型(比如DetailViewController) switchScreen(storyboardName: "Main", viewControllerName: "DetailVC", targetType: DetailViewController.self)
方案二:元类型参数直接转换
如果不想用泛型,也可以通过传入元类型参数,直接用参数的类型做转换:
extension UIViewController { func switchScreen(storyboardName: String, viewControllerName: String, targetType: UIViewController.Type) { let mainStoryboard = UIStoryboard(name: storyboardName, bundle: Bundle.main) if let viewController = mainStoryboard.instantiateViewController(withIdentifier: viewControllerName) as? targetType { self.present(viewController, animated: true, completion: nil) } } }
调用示例和方案一一致,传入目标ViewController.self即可。
错误原因说明
- 原代码中
vcc: UIViewController是传入实例对象,不是类型,所以as? vcc会被Swift当作类型名查找,自然找不到。 - 添加
.Type后参数变成vcc: UIViewController.Type(即元类型),但as? vcc的写法错误——Swift要求类型转换时必须使用明确的类型标识符,不能直接用参数名,这时候泛型或者直接使用元类型参数的类型是正确的写法。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

