Swift Version:5.0
RXSwift Version:5.0
复制代码
本文介绍的是如何使用 RX 构建 UITableView,需对 Swift 有基础的了解。共 1100 字,阅读需 10 min。git
先说一下构建的主要步骤,这样你们能更好的理解代码。github
使用 RXSwift 构建 UITableView 的步骤 swift
Observable
类型的数据源在咱们开始以前,咱们须要在项目中集成 RXSwift,具体步骤可参见 RXSwift。成功集成以后,咱们须要在要使用 RXSwift 的文件中导入它:bash
import RxSwift
复制代码
接着,咱们要建立一个 DisposeBag
类型的全局变量(必定要是全局变量
):闭包
let disposeBag = DisposeBag()
复制代码
关于 DisposeBag 的做用: DisposeBag 对于 RX 至关于 ARC 对于 iOS,即它是 RX 管理对象内存的一种方式。
异步
最后,将须要使用的 cell 进行注册:async
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
复制代码
OK,到如今为止,咱们已经完成了全部的准备工做。接下来,咱们能够根据上面的步骤来构建 tableView 了。ide
Observable
类型的数据源首先,咱们须要构建 Observable
类型的数据源。至于为何要构建 Observable
类型的数据,咱们能够从 RXSwift 的文档上一探究竟。ui
它的文档上是这么写的:Every Observable sequence is just a sequence. The key advantage for an Observable vs Swift's Sequence is that it can also receive elements asynchronously
。这句话的意思是说,可观察序列和 Swift 的原生序列本质上是同样的,但它们有一个最主要的不一样,那就是可观察序列能够异步接受元素
。spa
经过下面的代码建立 Observable
类型的数据源:
let texts = ["Objective-C", "Swift", "RXSwift"]
let textsObservable = Observable.from(optional: texts)
复制代码
此时,你用 option 键查看 textsObservable 属性的类型,应该显示的是 Observable<String>
。
可供使用的数据源已经构建完成,接下来须要将数据源与 tableView 绑定。
经过下面代码进行绑定(不要忘记最后的 .disposed(by: disposeBag)
):
textsObservable.bind(to: tableView.rx
.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (row, text, cell) in
cell.textLabel?.text = text
}
.disposed(by: disposeBag)
复制代码
在绑定方法的闭包中,咱们须要定义三个变量,三个变量分别有如下含义:
indexPath.row
texts[row]
经过下面代码进行绑定(cell 的点击事件):
tableView.rx.itemSelected.bind { (indexPath) in
print(indexPath)
}
.disposed(by: disposeBag)
复制代码
一样,不要忘记最后的 disposed 。
到这里,咱们就完成了经过 RX 构建一个简单的 tableView 。若是你对 tableView 还有一些自定义的需求,可经过第四步骤完成。
经过下面的代码设置代理:
tableView.rx.setDelegate(self).disposed(by: disposeBag)
tableView.rx.setDataSource(self).disposed(by: disposeBag)
复制代码
而后,你就能够实现相关的代理方法来进行自定义了,以设置高度举例:
extension ALGExploreDetailVC: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
}
复制代码
注意:若是你不须要使用 UITableViewDelegate/UITableViewDataSource 的委托方法的话,你是能够不写的。
// 不使用 RX 的话,须要实现代理方法
tableView.delegate = self
tableView.dataSource = self
extension ViewController: UITableViewDelegate, UITableViewDataSource {
....
}
// 使用 RX
// 绑定便可,不需写上面的代码
textsObservable.bind(to: tableView.rx
.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (row, text, cell) in
cell.textLabel?.text = "\(text)"
}
.disposed(by: disposeBag)
复制代码
若是使用 RX 绑定了 tableView ,再使用下面的代码就不对了,咱们需使用 RX 设置代理的方法。
tableView.delegate = self
复制代码
.disposed(by: disposeBag)
,释放内存import UIKit
import RxSwift
class TestViewController: UIViewController {
var tableView = UITableView(frame: .zero)
let kCellHeight: CGFloat = 40
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
setupSubviews()
}
}
extension TestViewController {
func setupSubviews() {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.safeEdges(to: view)
//1.建立可观察数据源
let texts = ["Objective-C", "Swift", "RXSwift"]
let textsObservable = Observable.from(optional: texts)
//2. 将数据源与 tableView 绑定
textsObservable.bind(to: tableView.rx
.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (row, text, cell) in
cell.textLabel?.text = text
}
.disposed(by: disposeBag)
//3. 绑定 tableView 的事件
tableView.rx.itemSelected.bind { (indexPath) in
print(indexPath)
}
.disposed(by: disposeBag)
//4. 设置 tableView Delegate/DataSource 的代理方法
tableView.rx.setDelegate(self).disposed(by: disposeBag)
}
}
extension TestViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
}
复制代码