Currently to load viewcontroller with same nibname I use code as follows
let recommendationVC : RecommendationVC = RecommendationVC(nibName: "RecommendationVC", bundle: nil)
I feel specifying nibname is unncessary as it is same as controller name. So i decided to use generics and infer type and nib name using generics
protocol NibIdentifiable {
static var nibNameIdentifier: String { get }
}
// MARK: - Indentifies each storyboard from its classname.
extension NibIdentifiable where Self: UIViewController {
static var nibNameIdentifier: String {
return String(describing: self)
}
}
extension UIViewController :NibIdentifiable
{
}
extension UIViewController {
func instantiate<Controller: UIViewController>(_: Controller.Type) -> Controller where Controller: NibIdentifiable {
guard let controller = Self(nibName:Controller.nibNameIdentifier,bundle:nil) as? Controller else {
fatalError("Could not dequeue cell with identifier: \(Controller.nibNameIdentifier)")
}
return controller
}
}
But on trying to create a VC instance,
let recommendationVC :RecommendationVC = UIViewController.instantiate()
receiving error Generic parameter 'Controller' could not be inferred
What is wrong in this approach?
Add the extension for UIViewController
extension UIViewController {
static func instantiateFromNib() -> Self {
func instantiateFromNib<T: UIViewController>(_ viewType: T.Type) -> T {
return T.init(nibName: String(describing: T.self), bundle: nil)
}
return instantiateFromNib(self)
}
}
and then use just like that
let myViewController = MyViewController.instantiateFromNib()
class Rec : UIViewController {
let r : String = "1231231"
}
protocol NibIdentifiable {
static var nibNameIdentifier: String { get }
}
// MARK: - Indentifies each storyboard from its classname.
extension NibIdentifiable where Self: UIViewController {
static var nibNameIdentifier: String {
return String(describing: self)
}
static func instantiate() -> Self {
guard let controller = Self(nibName:Self.nibNameIdentifier,bundle:nil) as? Self else {
fatalError("Could not dequeue cell with identifier: \(Self.nibNameIdentifier)")
}
return controller
}
}
extension UIViewController : NibIdentifiable {
}
let x : Rec = Rec.instantiate()
This must works.
In my case i use some Storyboardable protocol. and initiate Controller from specific storyboard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With