在日常的 iOS 开发中, UITableView是用得特别多的.
也许使用的最多的是 UITableViewController
了,重写需要的几个方法就OK了.
从 iOS 2.0 到 iOS 8 UITableView 本身也在不断的进化. 后来出现了 UICollectionView
当我在 UITableViewController 重复做着类似的事情时,
我遇到了 objc.io
它第一期中文章: Lighter View Controllers
他让我认识到,我以前对 Apple 提供的这一套东西,接受却缺少反思(不过在我看这文章之前,我还没正式做 iOS 开发)
但是,虽然篇文章,写我觉得写 UITableView的代码写得很漂亮的, 但是重复的代码还在不断的写,
于是我想起了 Android 平台的 ArrayAdapter, 我知道很多人都是继承 BaseAdapter的, 但是继承ArrayAdapter却会有更多的好处.
比如有泛型一些 Stub代码就不用了.
那么在 iOS 中我要怎么做呢? 幸好 Swift 为我们也带来的泛型
先从一个使用实例说起, 例如我需要一个文章列表的 UITableViewDataSource
那么我只需要写如下的代码即可:
class ArticleItemTableViewDataSource<T:ArticleItem>:GenericDataSource<T>{
init(articleItems:[T]){
super.init(items:articleItems)
}
override func configureTableViewCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
let itemCell = cell as! ArticleItemTableViewCell
let item = itemAtIndexPath(indexPath)
itemCell.bind(item)
}
override class var reuseIdentifier:String{
return ArticleItemTableViewCell.reuseIdentifier
}
}
然后就可以用了:
tableView.registerNib(ArticleItemTableViewCell.nib, forCellReuseIdentifier: ArticleItemTableViewCell.reuseIdentifier)
dataSource = ArticleItemTableViewDataSource(articleItems: [])
tableView.dataSource = dataSource
实现泛型的基类GenericDataSource
却是有一点曲折.
因为 Swift 为了与 Objective-C的交互性,做了一些限制 不能直接在 UITableView的方法中使用泛型类型的参数 .
所以必须再加一层包装, 这也就是我所实现的 GenericDataSource
class GenericDataSource<T>:SimpleDataSourceBridge{
private var items = [T]()
init(items:[T]){
self.items = items
}
func updateItems(items:[T]){
self.items = items
}
func itemAtIndexPath(indexPath:NSIndexPath) -> T{
return items[indexPath.row]
}
override func numberOfRows() -> Int {
return self.items.count
}
}
而让 SimpleDataSourceBridge
不直接调用泛型的方法,而是调用实现的另一个方法:
即如此:
final func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfRows()
}
注意上面方法的修饰 final
这是为了保证子类不再重写些方法了. 而应该去重写numberOfRows()
方法.
而这方法在泛型类中已经实现
到此一个支持泛型的 UITableViewDataSource 基类这是这样样子了, 我使用起来觉得很开心
两个类,全部源代码在这里:
https://gist.github.com/banxi1988/cbd5953dea41d20c833e
泛型的子类也得是泛型,所以注意我使用的子类的
class ArticleItemTableViewDataSource<T:ArticleItem>:GenericDataSource<T>
可以看到代码,基于对于弱化的 UICollectionView 也提供了支持. 简单的情况也可使用.
最后: 希望对大家有帮助.
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.