有没有一种方法可以使用RxSwift在UICollectionView上强制reloadData?

时间:2019-04-01 21:18:24

标签: rx-swift

我使用BehaviorSubject将UICollectionView绑定到实体数组,并且一切正常,数据已从网络加载并正确显示。

问题是,根据用户操作,我想更改UICollectionView使用的CellType并强制集合重新创建所有单元格,我该怎么做?

我的绑定代码如下:

self.dataSource.bind(to: self.collectionView!.rx.items) {
   view, row, data in

   let indexPath = IndexPath(row: row, section: 0)

   var ret: UICollectionViewCell? = nil
   if (self.currentReuseIdentifier == reuseIdentifierA) {
      // Dequeue cell type A and bind it to model
      ret = cell
   } else {
      // Dequeue cell type B and bind it to model
      ret = cell
   }

   return ret!
}.disposed(by: disposeBag)

3 个答案:

答案 0 :(得分:1)

作为一种解决方法,您可以发出一个空列表,然后发出一个实际数据以强制collectionView重新加载,如下所示:

dataSource.onNext([])
dataSource.onNext([1,2,3])

答案 1 :(得分:0)

解决Rx中问题的一般方法是考虑您希望输出效果如何以及哪些输入效果会影响它。

在您的情况下,输出效果是表格视图的显示。您已经确定了两个输入效果“从网络加载数据”和“用户操作”。为了使可观察链正常工作,您将必须以某种方式组合两个输入效果以获得所需的行为。我不能说在没有更多信息的情况下如何进行合并,但是这里有一篇文章解释了大多数可用的合并运算符:https://medium.com/@danielt1263/recipes-for-combining-observables-in-rxswift-ec4f8157265f

答案 2 :(得分:0)

我认为您可以使用不同的数据类型来创建单元格

import Foundation
import RxDataSources

enum SettingsSection {
    case setting(title: String, items: [SettingsSectionItem])
}

enum SettingsSectionItem {
    case bannerItem(viewModel: SettingSwitchCellViewModel)
    case nightModeItem(viewModel: SettingSwitchCellViewModel)
    case themeItem(viewModel: SettingCellViewModel)
    case languageItem(viewModel: SettingCellViewModel)
    case contactsItem(viewModel: SettingCellViewModel)
    case removeCacheItem(viewModel: SettingCellViewModel)
    case acknowledgementsItem(viewModel: SettingCellViewModel)
    case whatsNewItem(viewModel: SettingCellViewModel)
    case logoutItem(viewModel: SettingCellViewModel)
}

extension SettingsSection: SectionModelType {
    typealias Item = SettingsSectionItem

    var title: String {
        switch self {
        case .setting(let title, _): return title
        }
    }

    var items: [SettingsSectionItem] {
        switch  self {
        case .setting(_, let items): return items.map {$0}
        }
    }

    init(original: SettingsSection, items: [Item]) {
        switch original {
        case .setting(let title, let items): self = .setting(title: title, items: items)
        }
    }
}

let dataSource = RxTableViewSectionedReloadDataSource<SettingsSection>(configureCell: { dataSource, tableView, indexPath, item in
            switch item {
            case .bannerItem(let viewModel),
                 .nightModeItem(let viewModel):
                let cell = (tableView.dequeueReusableCell(withIdentifier: switchReuseIdentifier, for: indexPath) as? SettingSwitchCell)!
                cell.bind(to: viewModel)
                return cell
            case .themeItem(let viewModel),
                 .languageItem(let viewModel),
                 .contactsItem(let viewModel),
                 .removeCacheItem(let viewModel),
                 .acknowledgementsItem(let viewModel),
                 .whatsNewItem(let viewModel),
                 .logoutItem(let viewModel):
                let cell = (tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as? SettingCell)!
                cell.bind(to: viewModel)
                return cell
            }
        }, titleForHeaderInSection: { dataSource, index in
            let section = dataSource[index]
            return section.title
        })

        output.items.asObservable()
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: rx.disposeBag)
  1. RxDataSources
  2. swiftHub