二、RxDataSources
1,RxDataSources 介紹
(1)如果我們的 tableview 需要顯示多個(gè) section、或者更加復(fù)雜的編輯功能時(shí),可以借助 RxDataSource 這個(gè)第三方庫幫我們完成。
(2)RxDataSource 的本質(zhì)就是使用 RxSwift 對(duì) UITableView 和 UICollectionView 的數(shù)據(jù)源做了一層包裝。使用它可以大大減少我們的工作量。
2,安裝配置
- CocoaPods
Podfile
pod 'RxDataSources', '~> 3.0'
- Carthage
Cartfile
github "RxSwiftCommunity/RxDataSources" ~> 3.0
-
手動(dòng)安裝
(1)首先將RxDataSources下載到本地,并引入到項(xiàng)目中來。? ??GitHub 主頁:https://github.com/RxSwiftCommunity/RxDataSources

(2)然后在代碼中將其 import 進(jìn)來即可。
import RxDataSources
3,單分區(qū)的 TableView
(1)假設(shè)我們要實(shí)現(xiàn)如下效果:

(2)可以有如下兩種寫法:
注意:RxDataSources 是以 section 來做為數(shù)據(jù)結(jié)構(gòu)的。所以不管我們的 tableView 是單分區(qū)還是多分區(qū),在使用 RxDataSources 的過程中,都需要返回一個(gè) section 的數(shù)組。
- 方式一:使用自帶的Section
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
class ViewController: UIViewController {
var tableView:UITableView!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//創(chuàng)建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創(chuàng)建一個(gè)重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)
//初始化數(shù)據(jù)
let items = Observable.just([
SectionModel(model: "", items: [
"UILable的用法",
"UIText的用法",
"UIButton的用法"
])
])
//創(chuàng)建數(shù)據(jù)源
let dataSource = RxTableViewSectionedReloadDataSource
<SectionModel<String, String>>(configureCell: {
(dataSource, tv, indexPath, element) in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(indexPath.row):\(element)"
return cell
})
//綁定單元格數(shù)據(jù)
items
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}
- 方式二:使用自定義的Section
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
class ViewController: UIViewController {
var tableView:UITableView!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//創(chuàng)建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創(chuàng)建一個(gè)重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)
//初始化數(shù)據(jù)
let sections = Observable.just([
MySection(header: "", items: [
"UILable的用法",
"UIText的用法",
"UIButton的用法"
])
])
//創(chuàng)建數(shù)據(jù)源
let dataSource = RxTableViewSectionedAnimatedDataSource<MySection>(
//設(shè)置單元格
configureCell: { ds, tv, ip, item in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")
?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = "\(ip.row):\(item)"
return cell
})
//綁定單元格數(shù)據(jù)
sections
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}
//自定義Section
struct MySection {
var header: String
var items: [Item]
}
extension MySection : AnimatableSectionModelType {
typealias Item = String
var identity: String {
return header
}
init(original: MySection, items: [Item]) {
self = original
self.items = items
}
}
4,多分區(qū)的 UITableView
(1)假設(shè)我們要實(shí)現(xiàn)如下效果:

(2)同樣有如下兩種寫法:
- 方式一:使用自帶的Section
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
class ViewController: UIViewController {
var tableView:UITableView!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//創(chuàng)建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創(chuàng)建一個(gè)重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)
//初始化數(shù)據(jù)
let items = Observable.just([
SectionModel(model: "基本控件", items: [
"UILable的用法",
"UIText的用法",
"UIButton的用法"
]),
SectionModel(model: "高級(jí)控件", items: [
"UITableView的用法",
"UICollectionViews的用法"
])
])
//創(chuàng)建數(shù)據(jù)源
let dataSource = RxTableViewSectionedReloadDataSource
<SectionModel<String, String>>(configureCell: {
(dataSource, tv, indexPath, element) in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(indexPath.row):\(element)"
return cell
})
//設(shè)置分區(qū)頭標(biāo)題
dataSource.titleForHeaderInSection = { ds, index in
return ds.sectionModels[index].model
}
//設(shè)置分區(qū)尾標(biāo)題
//dataSource.titleForFooterInSection = { ds, index in
// return "footer"
//}
//綁定單元格數(shù)據(jù)
items
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}
- 方式二:使用自定義的Section
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
class ViewController: UIViewController {
var tableView:UITableView!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//創(chuàng)建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創(chuàng)建一個(gè)重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)
//初始化數(shù)據(jù)
let sections = Observable.just([
MySection(header: "基本控件", items: [
"UILable的用法",
"UIText的用法",
"UIButton的用法"
]),
MySection(header: "高級(jí)控件", items: [
"UITableView的用法",
"UICollectionViews的用法"
])
])
//創(chuàng)建數(shù)據(jù)源
let dataSource = RxTableViewSectionedAnimatedDataSource<MySection>(
//設(shè)置單元格
configureCell: { ds, tv, ip, item in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")
?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = "\(ip.row):\(item)"
return cell
},
//設(shè)置分區(qū)頭標(biāo)題
titleForHeaderInSection: { ds, index in
return ds.sectionModels[index].header
}
)
//綁定單元格數(shù)據(jù)
sections
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}
//自定義Section
struct MySection {
var header: String
var items: [Item]
}
extension MySection : AnimatableSectionModelType {
typealias Item = String
var identity: String {
return header
}
init(original: MySection, items: [Item]) {
self = original
self.items = items
}
}