Swift Version: 5.0 RXSwift Version: 5.0Copy the code
This article describes how to build a UITableView using RX, requiring a basic understanding of Swift. A total of 1100 words, 10 minutes to read.
Let’s talk about the main steps of the build so you can understand the code better.
Steps to build a UITableView using RXSwift
- build
Observable
Data source of type - Bind the data source to the tableView
- Bind tableView events (e.g. cell click events)
- Set the tableView Delegate/DataSource Delegate method (optional, as required)
The preparatory work
Before we can start, we need to integrate RXSwift into the project, as described in RXSwift. After successful integration, we need to import RXSwift in the file we want to use:
import RxSwift
Copy the code
Next, we create a global variable of type DisposeBag (it must be global) :
let disposeBag = DisposeBag()
Copy the code
What DisposeBag does: DisposeBag is to RX what ARC is to iOS, that is, it is a way for RX to manage object memory.
Finally, register the cell you need to use:
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
Copy the code
OK, so far, we have finished all the preparation work. Now we can follow the steps above to build the tableView.
buildObservable
Data source of type
First, we need to build a data source of type Observable. To see why you want to build Observable data, look at the RXSwift documentation.
Here’s what its documentation says: 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. What this means is that an observable sequence is essentially the same as Swift’s native sequence, but with one major difference: observable sequences can accept elements asynchronously.
Create a data source of type Observable with the following code:
let texts = ["Objective-C"."Swift"."RXSwift"]
let textsObservable = Observable.from(optional: texts)
Copy the code
In this case, you use the Option key to view the type of the textsObservable property, which should display Observable
.
Now that the data source is built for you to use, you need to bind the data source to the tableView.
Bind the data source to the tableView
Bind with the following code (don’t forget the final.disposed(by: disposeBag)) :
textsObservable.bind(to: tableView.rx
.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (row, text, cell) incell.textLabel? .text = text } .disposed(by: disposeBag)Copy the code
In the closure of the binding method, we need to define three variables with the following meanings:
- The first variable is the number of rows in the current cell, i.e. :
indexPath.row
- The second variable is the element of the current row number index of the observable sequence, that is:
texts[row]
- The third variable is the current cell
The event that binds the tableView
Bind (cell click events) with the following code:
tableView.rx.itemSelected.bind { (indexPath) in
print(indexPath)
}
.disposed(by: disposeBag)
Copy the code
Also, don’t forget the final disposed.
So at this point, we’re done building a simple tableView with RX. If you need to customize your tableView, you can do it in step 4.
Set the tableView Delegate/DataSource Delegate method
Set up the agent with the following code:
tableView.rx.setDelegate(self).disposed(by: disposeBag)
tableView.rx.setDataSource(self).disposed(by: disposeBag)
Copy the code
You can then implement the relevant proxy methods to customize the height, for example:
extension ALGExploreDetailVC: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return100}}Copy the code
Note: if you don’t need to use a UITableViewDelegate/UITableViewDataSource delegate, you can not write.
Delegate = self tableView.dataSource = self extension ViewController: UITableViewDelegate, UITableViewDataSource { .... Textsobservable. bind(to: tableView.rx.items (cellIdentifier:"Cell", cellType: UITableViewCell.self)) { (row, text, cell) incell.textLabel? .text ="\(text)"
}
.disposed(by: disposeBag)
Copy the code
If RX is used to bind the tableView, then the following code is not correct, we need to use RX to set the proxy method.
tableView.delegate = self
Copy the code
conclusion
- Using RX makes code concise and easy to read
- Call after using RX statement
.disposed(by: disposeBag)
, free memory
The complete code
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 = falsetableView.safeEdges(to: view) //1. Create an observable data sourcelet texts = ["Objective-C"."Swift"."RXSwift"]
lettextsObservable = Observable.from(optional: texts) //2. Bind (to: tableView.rx. Items (cellIdentifier:"Cell", cellType: UITableViewCell.self)) { (row, text, cell) incell.textLabel? .text = text } .disposed(by: disposeBag) //3. Binding tableView event tableView. Rx. ItemSelected. Bind {(indexPath)in
print(indexPath) } .disposed(by: disposeBag) //4. Set tableView.rx.setDelegate(self). Disposed (by: disposeBag) } } extension TestViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {return100}}Copy the code
reference
- RX
- Observe array in Swift 3 using RxSwift