目的:制作一个通用的ViewController和TableViewController,它能够从现有的故事板中返回自己,并由其他视图控制器进行子类化,并允许它们使用此功能.
class GenericTableViewController: UITableViewController
{
//MARK: Storyboard
class func storyboardName() -> String
{
return ""
}
class func storyboardIdentifier() -> String
{
return ""
}
class func existingStoryboardControllerTemplate() -> Self
{
return UIStoryboard.storyboardWithName(storyboardName()).instantiateViewControllerWithIdentifier(storyboardIdentifier()) as! Self
}
}
Run Code Online (Sandbox Code Playgroud)
问题是..编译器强迫我将Self更改为此"GenericTableViewController",如果我更改它...它抱怨我不再返回"Self".
有什么东西能解决这个问题吗?
Tom*_*min 23
执行以下操作应该有效:
class func existingStoryboardControllerTemplate() -> Self {
return existingStoryboardControllerTemplate(self)
}
private class func existingStoryboardControllerTemplate<T>(type: T.Type) -> T {
return UIStoryboard(name: storyboardName(), bundle: nil).instantiateViewControllerWithIdentifier(storyboardIdentifier()) as! T
}
Run Code Online (Sandbox Code Playgroud)
基本上你创建了一个通用版本existingStoryboardControllerTemplate
并添加了一个额外的方法来帮助编译器推断出它的类型T
.
基于 Tomas Camin 的答案,这里有UIViewController
Swift 3 的扩展。
extension UIViewController {
class func fromStoryboard(_ name: String, in bundle: Bundle? = nil, withIdentifier id: String? = nil) -> Self? {
return fromStoryboard(UIStoryboard(name: name, bundle: bundle), withIdentifier: id)
}
class func fromStoryboard(_ storyboard: UIStoryboard, withIdentifier id: String? = nil) -> Self? {
return fromStoryboard(storyboard, withIdentifier: id, as: self)
}
private class func fromStoryboard<T>(_ storyboard: UIStoryboard, withIdentifier id: String? = nil, as type: T.Type) -> T? {
return storyboard.instantiateViewController(withIdentifier: id ?? "\(type)") as? T
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的故事板视图控制器标识符与其类名称匹配,则只需使用fromStoryboard(name:)
名称调用类函数即可。
let viewController = MyCustomViewController.fromStoryboard("Main")
Run Code Online (Sandbox Code Playgroud)
否则,请提供标识符。
let viewController = MyCustomViewController.fromStoryboard("Main", withIdentifier: "ID")
Run Code Online (Sandbox Code Playgroud)
如果您已经有故事板的实例,则可以使用它。
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = MyCustomViewController.fromStoryboard(storyboard, withIdentifier: "ID")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5661 次 |
最近记录: |