简体   繁体   中英

RxSwift: Reacting to different cell types

I'm using RxSwift on a project, where I have a DataSource with different ViewItems . That's my DataSource configuration:

let dataSource = RxTableViewSectionedReloadDataSource<SectionedViewItem>(configureCell: { _, tableView, indexPath, item in

            if let viewItem = item as? BannerViewItem {
                guard let cell = tableView.dequeueReusableCell(withIdentifier: BannerCell.Key, for: indexPath) as? BannerCell else { fatalError() }
                cell.configureBindings(itemSource: viewItem)
                return cell
            } else if let viewItem = item as? CarSpecificationViewItem {
                guard let cell = tableView.dequeueReusableCell(withIdentifier: CarSpecificationCell.Key, for: indexPath) as? CarSpecificationCell else { fatalError() }
                cell.configureBindings(itemSource: viewItem)
                return cell
            } else if let viewItem = item as? CarBenefitViewItem {
                guard let cell = tableView.dequeueReusableCell(withIdentifier: CarBenefitCell.Key, for: indexPath) as? CarBenefitCell else { fatalError() }
                cell.configureBindings(itemSource: viewItem)
                return cell
            } else if let viewItem = item as? FavoriteHeaderViewItem {
                guard let cell = tableView.dequeueReusableCell(withIdentifier: CarFavoritesCell.Key, for: indexPath) as? CarFavoritesCell else { fatalError() }
                cell.configureBindings(itemSource: viewItem)
                return cell
            } else {
                return UITableViewCell()
            }
        })

Then I bind it to my ViewModel :

viewModel.dataSource.bind(to: tableView.rx.items(dataSource: dataSource)).disposed(by: disposeBag)

I subscribe to the selection events in the following way:

tableView.rx
    .modelSelected(CarSpecificationViewItem.self)
    .subscribe(tableViewRowSelected)
    .disposed(by: disposeBag)

This approach worked fine as long as I only reacted to CarSpecificationViewItem . Now I have activated userInteraction for CarFavoritesCell and subscribe to it's events as well:

tableView.rx
    .modelSelected(FavoriteHeaderViewItem.self)
    .subscribe(test)
    .disposed(by: disposeBag)

But this started to produce errors. I get a crash when tapping on my FavoriteHeaderViewItem:

Thread 1: Fatal error: Failure converting from Optional(CLCarRentalCore.FavoriteHeaderViewItem) to CarSpecificationViewItem

What could be the origin of the problem? Thanks in advance!

I solved the problem going one level higher and choosing ViewItemProtocol.self as my selected model, since all my ViewItems conform to that protocol. I still do not understand why the approach on my question didn't work though...

tableView.rx
    .modelSelected(ViewItemProtocol.self)
    .subscribe(onNext: { [weak self] viewItem in
        switch viewItem {
        case let item as CarSpecificationViewItem:
            self?.carSpecificationSelected(for: item)
        case is FavoriteHeaderViewItem:
            self?.toggleLike()
        default:
            return
        }
    })
    .disposed(by: disposeBag)
tableView.rx.modelSelected(Any.self)
                .subscribe(onNext: { [weak self] model in
                    guard let `self` = self  else { return }
                    switch model {
                        case is BannerViewItem:
                        let _model =  model as! BannerViewItem
                            // do your stuff
                            case is CarSpecificationViewItem
                            let _model =  model as! CarSpecificationViewItem 
                          // do your stuff
                          case is CarBenefitViewItem:
                          let _model =  model as! CarBenefitViewItem                       
                           // do your stuff
                           case is FavoriteHeaderViewItem:
                           let _model =  model as! FavoriteHeaderViewItem                       
                           // do your stuff
                           default: break

                           }
                       })
                .disposed(by: bag)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM