Reputation: 3202
I want to call the instantiateViewControllerWithIdentifier
method on a Storyboard to get a view controller. But I want to do it with generics for code reuse and simplicity.
let viewController = StoryboardHelper.viewControllerFromStoryboard<ChooseProviderViewController>()
class func viewControllerFromStoryboard<T>() -> T {
let storyboard = mainStoryboard()
let viewController = storyboard.instantiateViewControllerWithIdentifier(resolveViewController(T)) as T
return viewController
}
private class func resolveViewController<T>() -> String {
if T is ChooseProviderViewController {
return chooseProviderViewControllerIdentifier;
}
return ""
}
Now, the above code is what I have at the moment, and how I would like the API to be. It would be nice to say "StoryboardHelper, here is the type of the view controller I want, go get the view controller instance for me".
So, in the end, I would like some way to do this:
let instanceOfXViewController = StoryboardHelper.viewControllerFromStoryboard<XViewController>()
let instanceOfYViewController = StoryboardHelper.viewControllerFromStoryboard<YViewController>()
Upvotes: 0
Views: 494
Reputation: 541
I have a answer for you but it will only work with Swift 1.2 (+), in 1.1 it will return a intance of the wrong (super) type. I changed it to a more general situation/naming but it is effectly the same problem. First since you only want to manage UIViewController
s you should restrict T. Like <T:UIViewController>
. Secondly you should/can pass the Type as an argument and create an instance of it.
import Foundation
class Helper {
class func instanceFromT<T:R>(T.Type) -> T {
return T.self()
}
}
class R {
required init () {
}
func me() -> String {
return "me is R"
}
}
class B : R {
override func me() -> String {
return "me is B"
}
}
class A : R {
override func me() -> String {
return "me is A"
}
}
let my = Helper.instanceFromT(A.self)
println(my.me()) // "me is A"
Upvotes: 1