提问人:Thomas Albert 提问时间:10/21/2023 更新时间:10/22/2023 访问量:41
Swift 中的强制转换不适用于泛型 UIViewController 子类
Cast in Swift does not work for a generic UIViewController subclass
问:
我有一个子类,泛型本身就是 的子类。ToastViewController
UIViewController
ToastContentView
UIView
class ToastViewController<ContentViewType: ToastContentView>: UIViewController {
}
class ToastContentView: UIView {
}
我正在使用自定义视图控制器转换,我需要将我的呈现视图控制器从实例转换为。ToastViewController
UIViewControllerContextTransitioning
if let toastVC = context.viewController(forKey: .to) as? ToastViewController<ToastContentView> {
Log.debug("OK")
} else {
Log.debug("NOT OK")
}
我有一些具体的子类,如定义:AlertViewController
final class AlertViewController: ToastViewController<AlertToastView> {
}
final class AlertToastView: ToastContentView {
}
但是之前的强制转换检查总是失败(而我确定视图控制器是 的实例)。AlertViewController
我怎样才能让它工作? 我显然不想将呈现视图控制器转换为具体的子类......
谢谢
答:
0赞
Sweeper
10/22/2023
#1
嗯,是 a ,而不是 ,所以你不能投射。AlertViewController
ToastViewController<AlertToastView>
ToastViewController<ToastContentView>
执行此操作的一个简单方法是引入一个协议,其中包含您需要的所有内容。ToastViewController
@MainActor
protocol AnyToastViewController: UIViewController {
// declare properties/methods you need from ToastViewController here
}
如果需要泛型类型,请向协议添加关联的类型要求:ContentViewType
associatedtype Content: ToastContentView
var contentView: Content { get }
ToastViewController
将符合它:
class ToastViewController<ContentViewType: ToastContentView>: UIViewController, AnyToastViewController {
然后你可以改为投射到。any AnyToastViewController
if let toastVC = context.viewController(forKey: .to) as? ToastViewController<ToastContentView> {
let content = toastVC.contentView
// and so on...
} else {
Log.debug("NOT OK")
}
请注意,您只能获取泛型类型的属性,或调用返回 .设置 类型的属性或调用作为参数的方法不是类型安全的。ContentViewType
ContentViewType
ContentViewType
ContentViewType
评论
Log.debug("Not OK: \(context.viewController(forKey: .to)))