RxSwift is awesome we know it and most of us have experienced it. We also know that it is very easy to learn but requires a different thought process making it a bit tough to wrap your head around it. In this post, we will be making a simple UITableView implementation using RxSwift and RxCocoa. No complex patterns to confuse you, the idea is to understand one thing at a time. If you are looking for without Rx implementation you can have a look here..
Getting started
- Create a project you can name it as per your choice select Storyboard
- Close xcode project
- Open terminal and cd <your project folder>
- Run pod init
- Run pod install
- Open your project from workspace file. Pod install will create a workspace file for you its almost always below your pbxproject file
- In the project you will see Pods folder expand it and open pod file it will look some thing like this

- Add pods for RxSwift and RxCocoa
- pod ‘RxSwift’, ‘~> 5’
- pod ‘RxCocoa’, ‘~> 5’
- Close the project again and run pod install in terminal
Setting up your UITableView
- Drop a
UITableView
in ViewController Scene of your stroy borad and set constraints 0,0,0,0 - Add a
UITableViewCell
in the table view and set its Identifier as “Cell” - Create a
@IBOutlet weak var tableView:UITableView!
and link your table view
Setting up your view controller
Start by importing RxSwift and RxCocoa in your view controller.
import RxCocoa import RxSwift
Create a dispose bag and data source
var fruitDic: BehaviorRelay<[[String : String]]> = BehaviorRelay(value: [["name":"apple"], ["name":"banana"], ["name":"cherries"], ["name":"grapes"], ["name":"lemon"], ["name":"orange"], ["name":"strawberry"], ["name":"tomato"]]) var disposeBag = DisposeBag()
In order to create our data source, we have used behaviour relay. It stores values that cannot be mutated. In order to change the data stored in a BehaviourRelay we must first extract it and update it after that we can put it back in BehaviourRelay. BehaviourRelay emits the latest data it has to all its subscribers. We need to subscribe to our data source but before that, we will setup tableview delegate
func inputTableView() { // Set tableview delegate. tableView.rx .setDelegate(self) .disposed(by: disposeBag) // Bind fruit dictionary and tableview fruitDic.asObservable() .bind(to: tableView.rx .items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { index, element, cell in // Write image, name for cell label. cell.textLabel?.text = element["name"] }.disposed(by: disposeBag) tableView.tableFooterView = UIView() }
Now call this function inputTableView() from your viewDidLoad and add the table view delegate method for row height. After this, you can run your project in the simulator to see the table view working. I have also added item selected subscription and the final Viewcontroller class looks like this.
// // ViewController.swift // RxSwiftUItableview // // Created by amarendra on 10/09/21. // import UIKit import RxCocoa import RxSwift class ViewController: UIViewController, UITableViewDelegate { @IBOutlet weak var tableView:UITableView! var fruitDic: BehaviorRelay<[[String : String]]> = BehaviorRelay(value: [["name":"apple"], ["name":"banana"], ["name":"cherries"], ["name":"grapes"], ["name":"lemon"], ["name":"orange"], ["name":"strawberry"], ["name":"tomato"]]) var disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() inputTableView() } func inputTableView() { // Set tableview delegate. tableView.rx .setDelegate(self) .disposed(by: disposeBag) // Bind fruit dictionary and tableview fruitDic.asObservable() .bind(to: tableView.rx .items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { index, element, cell in // Write image, name for cell label. cell.textLabel?.text = element["name"] }.disposed(by: disposeBag) // added did select equivalent and printed corresponding name tableView.rx.itemSelected.subscribe { [weak self] (indexPath) in print(self!.fruitDic.value[indexPath.row]["name"]!) }.disposed(by: disposeBag) tableView.tableFooterView = UIView() } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 40 } }