0

I want to pass expandable tableView from default to Rx, but i found trouble that i can't use properly numberOfRownInSection.

Now the logic is... when you struct has flag isExpandable = false, row count is 0

What i have is tableView with static data (struct will provide below). HeaderView as title and cells as expandable content.

Toggle func:

func toggleCell(_ section: Int) {

    var indexPaths = [IndexPath]()

    for row in data[section].items.indices {
        let indexPath = IndexPath(row: row, section: section)
        indexPaths.append(indexPath)
    }

    let isExpanded = data[section].isExpanded
    data[section].isExpanded = !isExpanded

    if isExpanded {
        categoriesTableView.deleteRows(at: indexPaths, with: .none)
    } else {
        categoriesTableView.insertRows(at: indexPaths, with: .none)
    }

}

Default tableView delegate:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: HomeViewCell = tableView.dequeueReusableCell(forIndexPath: indexPath)
    cell.categoryLabel.text = data[indexPath.section].items[indexPath.row].title ?? ""
    return cell
}

func numberOfSections(in tableView: UITableView) -> Int {
    return data.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if !data[section].isExpanded {
        return 0
    }

    return data[section].items.count
}

Struct

var data: [CategoriesSectionData] = [CategoriesSectionData(header: "Elektro",            items: [CategoriesCellData(price: 12.99, title: "Gärtner 1"),
                                                                                                 CategoriesCellData(price: 15.30, title: "Gärtner 2"),
                                                                                                 CategoriesCellData(price: 25.99, title: "Gärtner 3")], isExpanded: false, icon: "home_menu_1"),
                                     CategoriesSectionData(header: "Gartenpflege",       items: [CategoriesCellData(price: 14.0, title: "Gärtner 1")], isExpanded: false, icon: "home_menu_2"),
                                     CategoriesSectionData(header: "Sanitär",            items: [], isExpanded: false, icon: "home_menu_3"),
                                     CategoriesSectionData(header: "Hausmeisterdienste", items: [], isExpanded: false, icon: "home_menu_4"),
                                     CategoriesSectionData(header: "Meisterprüfung",     items: [], isExpanded: false, icon: "home_menu_3"),
                                     CategoriesSectionData(header: "Gartenpflege",       items: [], isExpanded: false, icon: "home_menu_2"),
                                     CategoriesSectionData(header: "Sanitär",            items: [], isExpanded: false, icon: "home_menu_1"),
                                     CategoriesSectionData(header: "Hausmeisterdienste", items: [], isExpanded: false, icon: "home_menu_4")]

To pass this to Rx i used following code but i have error when insert/delete rows because i don't want to clear my dataSource and can't set numberOfRownInSection to not display cells with expandable flag.

let dataSource = RxTableViewSectionedReloadDataSource<CategoriesSectionData>(
        configureCell: { ds, tv, indexPath, item in

            let cell: HomeViewCell = tv.dequeueReusableCell(forIndexPath: indexPath)
            cell.categoryLabel.text = item.title ?? ""
            return cell
        },

        titleForHeaderInSection: { ds, index in
            return ds.sectionModels[index].header
        }
    )

    self.dataSource = dataSource

    Observable.just(data)
        .bind(to: categoriesTableView.rx.items(dataSource: dataSource))
        .disposed(by: disposeBag)

    categoriesTableView.rx
        .setDelegate(self)
        .disposed(by: disposeBag)
George Heints
  • 1,303
  • 3
  • 20
  • 37

1 Answers1

2

Try looking on RxDataSources repo on GitHub. There is an example on how to do this. You can bind cellViewModels to tableview in Rx way

Serban Coroiu
  • 41
  • 1
  • 2