I'm trying to write a little extension in Swift to handle instantiation of a UIViewController
from a storyboard.
My idea is the following: Since UIStoryboard
's method instantiateViewControllerWithIdentifier
needs an identifier to instantiate a given storyboard's view controller, why don't assign every view controller in my storyboard an identifier equal to its exact class name (i.e a UserDetailViewController
would have an identifier of "UserDetailViewController"), and, create a class method on UIViewController that would:
- accept a
UIStoryboard
instance as a unique parameter - get the current class name as a string
- call
instantiateViewControllerWithIdentifier
on the storyboard instance with the class name as a parameter - get the newly created
UIViewController
instance, and return it
So, instead of (which repeats the class name as a string, not very nice)
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("UserDetailViewController") as UserDetailViewController
it would be:
let vc = UserDetailViewController.instantiateFromStoryboard(self.storyboard!)
I used to do it in Objective-C with the following category:
+ (instancetype)instantiateFromStoryboard:(UIStoryboard *)storyboard
{
return [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass([self class])];
}
But I'm completely stuck with the Swift version. I hope is that there is some kind of way to do it. I tried the following:
extension UIViewController {
class func instantiateFromStoryboard(storyboard: UIStoryboard) -> Self {
return storyboard.instantiateViewControllerWithIdentifier(NSStringFromClass(Self))
}
}
Returning Self
instead of AnyObject
allows the type inference to work. Otherwise, I would have to cast every single return of this method, which is annoying, but maybe you have a better solution?
This gives me the error: Use of unresolved identifier 'Self'
The NSStringFromClass
part seems to be the problem.
What do you think?
Is there any way to return
Self
from class functions?How would you get this working without the need to cast the return value every time? (i.e keeping
-> Self
as return value)