之前我们说过了运用面向协议的思想为控件添加 action 今天我们再来写一个基于 Storyboard 的初始化方法。在我的项目中,我没有将所有的 controller 都放在一个 Storyboard 文件中,原因有两个:
- 当
Controller很多的时候不方便查找对应的Storyboard。 - 打开
Storyboard会非常卡。
所以我将 Controller 拆分成一个个的 Storyboard 文件。在对应的类中,我需要在每个类都写上一个初始化方法:
static func instantiate() -> HomeViewController {
return UIStoryboard(name: .home)
.instantiateViewControllerWithClass(type: HomeViewController.self)
}
当你的 App 页面非常多的时候你会发现到处都是 instantiate() 方法,所以我们需要用 Swift 中强大的 Protocol 思想进行一次优化了。
首先我们需要声明一个协议 StoryboardLoadable:
protocol StoryboardLoadable where Self: UIViewController {
}
在协议中我们可以什么都不用写。接下来我们扩展这个协议:
extension StoryboardLoadable {
static func instantiate() -> Self {
/// 移除类的 viewcontroller 后缀,创建 storyboard 名
let sbName = "\(self)".removingSuffix("ViewController")
return UIStoryboard(name: sbName).instantiateViewControllerWithClass(type: Self.self)
}
}
举个例子,我的登录页面的控制器名称为 LoginViewController,对应的 Storyboard 名称为 Login,所以我需要执行 let sbName = "\(self)".removingSuffix("ViewController") 来生成 Storyboard 名称。
然后我们在我们的类中遵循这个协议即可。
class LoginViewController: StoryboardLoadable {
}
以后就可以在其他地方这样初始化你的类了:
let loginVC = LoginViewController.instantiate()