Search code examples
iosswiftuitableviewreactive-programmingrx-swift

Automatically Scroll UITableView to bottom in Rx Swift


I am new to RX Swift and need to display data in table view such that it automatically displays the last cell of the table(Scrolled to bottom by Default). Here is my code to bind data:

private var dataArray = Variable<[Message]>([])
private let bag = DisposeBag()

dataArray.asObservable()
    .bindTo(tableView.rx.items) { (tableView, row, msg) in
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!

        cell.textLabel?.text = obj.title
        return cell
    }
    .addDisposableTo(bag)

This code displays data to table view but does not scroll table View to bottom every time a new cell is added. I probably need to add the below line but not sure which rx-swift operator to use?

tableView.setContentOffset(CGPoint(x: 0, y : CGFloat.greatestFiniteMagnitude), animated: true)

Thanks in Advance.

On a related note, would really appreciate if some one can suggest a good open source sample project made in rx-swift which we can refer.


Solution

  • You will want to set content offset everytime dataArray emit's a new value.

    A good solution then would be

    dataArray.asObservable().map { CGPoint(x: 0, y: CGFloat.greatestFiniteMagnitude) }
      .bindTo(tableView.rx.contentOffset)
      .addDisposableTo(bag)
    

    Otherwise, you could simply do

    dataArray.asObservable()
        .do(onNext: { 
            self.tableView.setContentOffset(CGPoint(x: 0, y : CGFloat.greatestFiniteMagnitude), animated: true) 
         })
        .bindTo(tableView.rx.items) { (tableView, row, msg) in
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
    
            cell.textLabel?.text = obj.title
            return cell
        }
        .addDisposableTo(bag)
    

    do(onNext:) is used to perform side effects when an observable emits a value. Those side effects will occurs once per subscriber.