如何使用is关键字判断对象是否为任意泛型UIHostingController?
检测任意泛型参数的UIHostingController实例
问题核心
Swift中使用is关键字判断泛型类时必须指定具体泛型参数,但UIHostingController的Content类型可能是任意视图(比如ModifiedContent、自定义View等),指定固定类型(如UIHostingController<AnyView>)会因为类型不匹配导致判断失败。
解决方案
方法1:利用Objective-C运行时(最简便)
UIHostingController继承自UIViewController,而Objective-C运行时不区分Swift泛型类的泛型参数,直接用isKind(of:)即可匹配任意Content类型的实例:
let vc = window.rootViewController?.children.last { $0.isKind(of: UIHostingController.self) }
方法2:纯Swift协议擦除(最优雅)
定义一个空协议,让所有UIHostingController的泛型实例自动遵守,通过协议实现类型擦除:
// 定义空协议 protocol AnyUIHostingController {} // 让所有UIHostingController实例遵守协议 extension UIHostingController: AnyUIHostingController {} // 使用方式 let vc = window.rootViewController?.children.last { $0 is AnyUIHostingController }
这种方法完全基于Swift类型系统,不依赖外部运行时,类型安全且代码简洁。
方法3:遍历类继承链(纯Swift无依赖)
通过遍历对象的类继承链,检查类名特征来判断:
import ObjectiveC.runtime func isAnyUIHostingController(_ vc: UIViewController) -> Bool { var currentType: Any.Type = type(of: vc) while let baseClass = currentType as? AnyClass { let className = String(describing: baseClass) if className.hasPrefix("UIHostingController<") { return true } currentType = class_getSuperclass(baseClass)! } return false } // 使用方式 let vc = window.rootViewController?.children.last { isAnyUIHostingController($0) }
这种方法不依赖Objective-C运行时的动态判断,但需要依赖类名格式,优雅度稍差。
内容的提问来源于stack exchange,提问作者mckeed
相关产品推荐
相关产品推荐

