DBIndexPath 是一个简单的包装结构体,围绕 IPSearchPath,使其能够定义一个索引路径枚举并在其案例中切换。这在 UITableViewDataSource 与 UITableViewDelegate 方法中特别有用,在这些方法中,您可能会根据处理的行执行不同的代码。
DBIndexPath 可以通过手动指定节/行,使用格式为“section,row”的字符串,或者使用现有的 NSIndexPath 实例创建。
public init(section: Int, row: Int)
public init?(_ indexPath: NSIndexPath)
public init(stringLiteral value: StringLiteralType)
DBIndexPath 使用 Xcode 7 beta 6 和 Swift 2.0 编写。
DBIndexPath 可以通过 Cocoapods 容易地安装
将以下内容放入您的 podfile 中
platform :ios, '8.0'
use_frameworks!
pod 'DBIndexPath', '~> 0.1'
然后运行以下命令进行安装
pod install
NSIndexPath 不遵循 RawRepresentable,因此不能用于枚举。它也不遵循字符串、字符以及任何整数或浮点数类型可转换的协议,因此不能静态定义。当我们需要根据索引路径执行不同的代码时,这使得编写可维护且无缺陷的代码变得困难。
这是与 Objective-C 兼容的旧方法
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.section == 0 {
if indexPath.row == 0 {
// Handle selection
} else if indexPath.row == 1 {
// Handle selection
}
} else if indexPath.section == 1 {
if indexPath.row == 0 {
// Handle selection
}
}
这并不是非常可维护且易出错的,因为当我们想添加新的行来处理时,我们必须更新每个包含此逻辑的函数。同时,还存在着输入索引时出错的可能性更大。
Swift 的元组和模式匹配让我们可以稍微简化这个情况
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
switch (indexPath.section, indexPath.row) {
case (0, 0):
// Handle selection
case (0, 1):
// Handle selection
case (1, 0):
// Handle selection
default:
assertionFailure("invalid indexPath: \(indexPath)")
}
}
这使得代码更易读,但仍然不能解决必须在每个函数位置定义这些索引的问题。
DBIndexPath 被设计为与枚举一起使用,允许您根据给定的索引路径进行切换。枚举允许在单个位置声明索引路径。这使得在将来添加新的索引路径变得更容易,无需复制/粘贴硬编码的信息。
当您向枚举添加新值时,所有的 switch 语句(不包括“default”情况)都会中断,迫使您更新它们以处理新值。
在您的视图控制器中定义一个从 DBIndexPath 继承的枚举,并使用字符串字面量
enum TableIndex: DBIndexPath {
case One = "0,0"
case Two = "0,1"
case Three = "1,0"
}
然后在包含传入的NSIndexPath的方法中,例如tableView(didSelectRowAtIndexPath:)
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let rawValue = DBIndexPath(indexPath), tableIndex = TableIndex(rawValue: rawValue) {
switch tableIndex {
case .One:
// Handle selection
case .Two:
// Handle selection
case .Three:
// Handle selection
}
} else {
assertionFailure("invalid indexPath: \(indexPath)")
}
}
现在,我们已经将确定我们所处理的索引路径的逻辑从代理函数中抽象出来,可以专注于处理行选择。
可能有一些情况,编译时已经知道所有表格视图的索引路径和行。换句话说,定义的枚举案例是所有将被使用的索引路径的详尽列表。
在这种情况下,DBIndexPathSwitchableProtocol可以简化代码
在您的视图控制器类中,声明对协议的遵从性
class ViewController: UITableViewController, DBIndexPathSwitchableProtocol {
typealias DBIndexPathType = TableIndex
enum TableIndex: DBIndexPath {
case One = "0,0"
case Two = "0,1"
case Three = "1,0"
}
}
然后您可以简化函数位置到
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
switch indexPathFromNSIndexPath(indexPath) {
case .One:
// Handle selection
case .Two:
// Handle selection
case .Three:
// Handle selection
}
}
MIT 许可证。详见LICENSE文件。