Xcode 的代码提示是没有办法验证字符串 (如: “Tychooo”) 的输入正确的, 我们在使用 storyboard 创建 UI 时, 经常会使用到 segue 的 identifier 来进行 viewController 跳转. 对其进行封装, 可以很好的减少自己手残输入错误时 debug 的时间成本. 我们一起来看一下 WWDC 中的 Demo.

我们首先定义一个协议 SegueHandlerType, 之后凡是需要用的 segue 跳转的 viewController 都需要循序此协议.

1
2
3
protocol SegueHandlerType {
associatedtype SegueIdentifier: RawRepresentable
}

在协议中指定一个关联类型 RawRepresentable, 已此来让我们可以对 segue 的 identifier 进行枚举.

接下来实现该协议的具体内容, 在此我们希望凡是循序此协议的类, 必须是 UIViewController 的子类, 同时限定 SegueIdentifier 关联类型的 rawValue 必须是 String 类型.

1
2
3
4
extension SegueHandlerType where Self: UIViewController,
SegueIdentifier.RawValue == String {
}

做好这些限定, 我们来封装 performSegue 方法. 在协议中实现如下方法.

1
2
3
func performSegue(identifier: SegueIdentifier, sender: AnyObject?) {
performSegue(withIdentifier: identifier.rawValue, sender: sender)
}

OK, Done!
我们在 UIViewController 中使用时需要定义一个关联类型是 String 的枚举. 来看一下示例.

1
2
3
4
5
6
7
8
9
class BaseCollectionViewController: UICollectionViewController,
SegueHandlerType {
enum SegueIdentifier: String {
case showFormulaDetail = "ShowFormulaDetail"
case showAddFormula = "ShowAddFormula"
}
}

而在进行 segue 跳转时, 我们就可以直接使用协议中的 performSegue 方法了.

1
self.performSegue(identifier: SegueIdentifier.showFormulaDetail, sender: nil)

虽然表面上看起来似乎我们将问题复杂化了, 但在结构相对复杂的控制器中, 频繁手动输入字符串出错时, Xcode 又不能未我们提供错误提醒. 无疑增加了我们 debug 的时间成本.

接下来我们来实现另外一个与 segue 跳转相关的常用方法的封装 func prepare(for segue: UIStoryboardSegue, sender: Any?), 我们在之前定义的协议中实现下面的方法.

1
2
3
4
5
6
7
8
func segueIdentifier(for segue: UIStoryboardSegue) -> SegueIdentifier {
guard
let identifier = segue.identifier,
let segueIdentifier = SegueIdentifier(rawValue: identifier) else {
fatalError("无效的 Segue Identifier")
}
return segueIdentifier
}

上面的方法接受一个 segue 实例, 判断其 identifier 是否与我们在 viewController 中定义的 case 相对应. 如果没有, 将在控制台输出 “无效的 Segue Identifier” .

我们来看一下在 viewController 中实际的应用.

1
2
3
4
5
6
7
8
9
10
11
12
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segueIdentifier(for: segue) {
case .showFormulaDetail:
let vc = segue.destination as! FormulaDetailViewController
case .showAddFormula:
let vc = segue.destination as! NewFormulaViewController
}
}

这样我们就可以很方便的枚举不同的 segue 了, 并且当我们输入错误的时候, Xcode 也能准确的报告问题所在.