LynAs
LynAs

Reputation: 6547

How to prepend data to tableview or collectionview using RxSwift

I can see that I can use Subject like Publish or Variable to add new element to table view or collection view and that will show properly at the end but what if need to add new data at the beginning of the table view. what to do then??

How can I prepend data to a observable sequence so that new data shows at the top of tableview or collection view ???

Upvotes: 2

Views: 1904

Answers (2)

LynAs
LynAs

Reputation: 6547

A complete look of what i was looking for

import UIKit
import RxSwift
import RxCocoa

struct Person {
    let name : String
    let age : Int

}
class ViewController: UIViewController {
    let personArray = [
        Person(name: "name1", age: 11),
        Person(name: "name2", age: 12),
        Person(name: "name3", age: 13)
    ]

    let disposeBag = DisposeBag()
    var items : Observable<[Person]>!

    @IBOutlet weak var mytable: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        items = Observable.just(personArray)
        bindData()
    }

    @IBAction func prependButtonAction(_ sender: UIButton) {
        let newPersonArray = [
            Person(name: "name -3", age: 11),
            Person(name: "name -4", age: 12)
        ]
        prependData(dataToPrepend: newPersonArray)
    }

    @IBAction func appendButtonAction(_ sender: UIButton) {
        let newPersonArray = [
            Person(name: "name 6", age: 11),
            Person(name: "name 7", age: 12)
        ]
        appendData(dataToAppend : newPersonArray)
    }



    private func bindData() {
        mytable.dataSource = nil
        items.bindTo(mytable.rx.items(cellIdentifier: "cell")) { (row, person, cell) in
            if let cellToUse = cell as? TableViewCell {
                cellToUse.label1.text = person.name
                cellToUse.label2.text = "\(person.age)"
            }
        }.addDisposableTo(disposeBag)
    }

    private func prependData(dataToPrepend : [Person]) {
        let newObserver = Observable.just(dataToPrepend)
        items = Observable.combineLatest(items, newObserver) {
            $1+$0
        }
        bindData()
    }


    private func appendData(dataToAppend : [Person]) {
        let newObserver = Observable.just(dataToAppend)
        items = Observable.combineLatest(items, newObserver) {
            $0+$1
        }
        bindData()
    }
}

Upvotes: 0

xandrefreire
xandrefreire

Reputation: 2326

You can use combineLatestoperator.

Initially, newData is an empty array, and when you add data to it, it is displayed at the top of tableView

    let data = [
        "A New Hope",
        "The Empire Strikes Back",
        "Return of the Jedi"
    ]

    let obsData = Observable.just(data)

    let newData = [
        "The Phantom Menace",
        "Attack of the Clones",
        "Revenge of the Sith"
    ]
    let obsNewData = Observable.just(newData)

    let items = Observable.combineLatest(obsData, obsNewData){
        $1+$0 
    }     

    items.bindTo(tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (row, film, cell) in
        cell.textLabel?.text = film
    }
    .addDisposableTo(disposeBag)

Upvotes: 2

Related Questions