如果我有一个类BaseViewController:UIViewController,并且我想要一种从Xib实例化这个viewController的方法,我可以这样做:
class func initFromXib()->BaseViewController?{
let nibName = String(NSStringFromClass(self).split(separator: ".").last ?? "")
let nib = UINib(nibName: nibName, bundle: nil)
return nib.instantiate(withOwner: nil, options: nil).first as? BaseViewController
}每当我需要从xib初始化ViewController时,我可以只说let vc = BaseViewController.initFromXib()。
但是假设我有一个名为HomeViewController:BaseViewController的viewController的子类。如果我说let home = HomeViewController.initFromXib(),这确实会成功地返回HomeViewController的一个实例(只要有一个这样命名的Xib ),但作为一个BaseViewController。这没什么错,我要做的就是
let vc = HomeViewController.initFromXib() as? HomeViewController一切都变得很酷。但是,有没有一种方法可以使initFromXib的返回类型成为它所源自的类的“泛型”类型,以便initFromXib始终返回正确类的类型?
发布于 2019-07-05 16:59:08
一种解决方案是具有关联类型的协议扩展,只需在适当的类中采用该协议
protocol XibInitializable {
associatedtype ControllerType : UIViewController = Self
static func initFromXib() -> ControllerType?
}
extension XibInitializable where Self : UIViewController {
static func initFromXib() -> ControllerType? {
let nibName = String(describing: Self.self)
let nib = UINib(nibName: nibName, bundle: nil)
return nib.instantiate(withOwner: nil, options: nil).first as? ControllerType
}
}现在你可以写
let vc = HomeViewController.initFromXib()https://stackoverflow.com/questions/56899670
复制相似问题