RxSwift重载动画中的RxDatasource don';更新数据源

RxSwift重载动画中的RxDatasource don';更新数据源,swift,uitableview,rx-swift,rxdatasources,Swift,Uitableview,Rx Swift,Rxdatasources,RxSwift[RxTableViewSectionedAnimatedDataSource]重新加载动画中的RxDatasource不更新数据源。我犯了什么错误?我甚至无法将我的动作与按钮正确绑定 TableDataSource和表编辑命令 struct TableDataSource { var header: String var items: [Item] var SectionViewModel: SectionViewModel } extension Ta

RxSwift[RxTableViewSectionedAnimatedDataSource]重新加载动画中的RxDatasource不更新数据源。我犯了什么错误?我甚至无法将我的动作与按钮正确绑定

TableDataSource和表编辑命令

struct TableDataSource {
    var header: String
    var items: [Item]
    var SectionViewModel: SectionViewModel
}

extension TableDataSource: AnimatableSectionModelType {
    var identity: String {
        return header
    }

type alias Item = Data

    init(original: TableDataSource, items: [Item]) {
        self = original
        self.items = items
        self.sectionViewModel = original.sectionViewModel
    }
}

enum TableViewEditingCommand {    
    case deleteSingle(IndexPath)
    case clearAll(IndexPath)
    case readAll(IndexPath)
}

struct SectionedTableViewState {

    var sections: [TableDataSource]

    init(sections: [TableDataSource]) {
        self.sections = sections
    }

    func execute(command: TableViewEditingCommand) -> SectionedTableViewState {
        var sections = self.sections
        switch command {

        // Delete single item from datasource
        case .deleteSingle(let indexPath):
            var items = sections[indexPath.section].items
            items.remove(at: indexPath.row)
            if items.count <= 0 {
                sections.remove(at: indexPath.section)
            } else {
                sections[indexPath.section] = TableDataSource(
                    original: sections[indexPath.section],
                    items: items) }

        // Clear all item from datasource with isUnread = false
        case .clearAll(let indexPath):
            sections.remove(at: indexPath.section)

        // Mark all item as read in datasource with isUnread = true
        case .readAll(let indexPath):
            var items = sections[indexPath.section].items
            items = items.map { var unread = $0
                if $0.isUnRead == true { unreadData.isUnRead = false }
                return unreadData
            }
            sections.remove(at: indexPath.section)
            if sections.count > 0 {
            let allReadItems = sections[indexPath.section].items + items
                sections[indexPath.section] = TableDataSource(
                    original: sections[indexPath.section],
                    items: allReadItems)
            }
        }
         return SectionedTableViewState(sections: sections)
    }
}
struct TableDataSource{
变量头:字符串
可变项目:[项目]
var SectionViewModel:SectionViewModel
}
扩展表数据源:AnimatableSectionModelType{
变量标识:字符串{
回流集管
}
类型别名项=数据
初始化(原始:TableDataSource,项:[Item]){
自我=原创
self.items=项目
self.sectionViewModel=原始的.sectionViewModel
}
}
枚举表视图编辑命令{
大小写deleteSingle(IndexPath)
大小写clearAll(IndexPath)
case readAll(indexath)
}
结构SectionTableViewState{
变量部分:[TableDataSource]
初始化(节:[TableDataSource]){
self.sections=节
}
func execute(命令:TableViewEditingCommand)->SectionedTableViewState{
var截面=自截面
开关命令{
//从数据源中删除单个项
case.deletesSingle(让indexPath):
var items=sections[indexPath.section].items
items.remove(位于:indexPath.row)
如果项目数为0.0{
让allReadItems=sections[indexPath.section].items+items
sections[indexPath.section]=TableDataSource(
原文:第[indexPath.section]节,
项目:所有阅读项目)
}
}
返回SectionedTableViewState(节:节)
}
}
这是我的控制器及其扩展


class ViewController: UIViewController, Storyboardable {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var closeButton: UIButton!
    @IBOutlet weak var titleText: UILabel!

    var viewModel: ViewModel!
    let disposeBag = DisposeBag()

    let sectionHeight: CGFloat = 70
    let dataSource = ViewController.dataSource()

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        bindInitials()
        bindDataSource()
        bindDelete()
    }

    private func bindInitials() {
        tableView.delegate = nil
        tableView.rx.setDelegate(self)
            .disposed(by: disposeBag)
        registerNibs()
    }

    private func registerNibs() {
        let headerNib = UINib.init(
            nibName: TableViewSection.identifier,
            bundle: nil)
        tableView.register(
            headerNib,
            forHeaderFooterViewReuseIdentifier: TableViewSection.identifier)
    }
}

extension ViewController: Bindable {

    func bindViewModel() {
        bindActions()
    }

    private func bindDataSource() {

        bindDelete()


        //        tableView.dataSource = nil
        //        Observable.just(sections)
        //            .bind(to: tableView.rx.items(dataSource: dataSource))
        //            .disposed(by: disposeBag)
    }

    private func bindDelete() {
        /// TODO: to check and update delete code to work properly to sink with clear all and mark all as read
        guard let sections = self.viewModel?.getSections() else {
            return
        }
        let deleteState = SectionedTableViewState(sections: sections)
        let deleteCommand = tableView.rx.itemDeleted.asObservable()
            .map(TableViewEditingCommand.deleteSingle)

        tableView.dataSource = nil
        Observable.of(deleteCommand)
            .merge()
            .scan(deleteState) {
                (state: SectionedTableViewState,
                command: TableViewEditingCommand) -> SectionedTableViewState in
                return state.execute(command: command) }
            .startWith(deleteState) .map { $0.sections }
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)
    }

    private func bindActions() {

        guard let openDetailsObserver = self.viewModel?.input.openDetailsObserver,
            let closeObserver = self.viewModel?.input.closeObserver else {
                return
        }
        viewModel.output.titleTextDriver
            .drive(titleText.rx.text)
            .disposed(by: disposeBag)

//        viewModel.input.dataSourceObserver
//            .mapObserver({ (result) -> [Data] in
//                return result
//            })
//            .disposed(by: disposeBag)

        /// Close button binding with closeObserver
        closeButton.rx.tap
            .bind(to: (closeObserver))
            .disposed(by: disposeBag)

        /// Tableview item selected binding with openDetailsObserver
        tableView.rx.itemSelected
            .map { indexPath in
                return (self.dataSource[indexPath.section].items[indexPath.row])
        }.subscribe(openDetailsObserver).disposed(by: disposeBag)
    }
}

extension ViewController: UITableViewDelegate {

    static func dataSource() -> RxTableViewSectionedAnimatedDataSource<TableDataSource> {
        return RxTableViewSectionedAnimatedDataSource(
            animationConfiguration: AnimationConfiguration(insertAnimation: .fade,
                                                           reloadAnimation: .fade,
                                                           deleteAnimation: .fade),
            configureCell: { (dataSource, table, idxPath, item) in
                var cell = table.dequeueReusableCell(withIdentifier: TableViewCell.identifier) as? TableViewCell
                let cellViewModel = TableCellViewModel(withItem: item)
                cell?.setViewModel(to: cellViewModel)
                return cell ?? UITableViewCell()
        }, canEditRowAtIndexPath: { _, _ in return true })
    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        guard var headerView = tableView.dequeueReusableHeaderFooterView(
            withIdentifier: TableViewSection.identifier)
            as? TableViewSection
            else { return UITableViewHeaderFooterView() }
        let viewModel = self.dataSource[section].sectionViewModel
        headerView.setViewModel(to: viewModel)
        headerView.dividerLine.isHidden = section == 0 ? true : false
        headerView.section = section

        let data = TableViewEditingCommand.clearAll(IndexPath(row: 0, section: section ?? 0))
//        /// Section button binding with closeObserver
//        headerView.sectionButton.rx.tap
//            .map(verseNum -> TableViewEditingCommand in (TableViewEditingCommand.deleteSingle))
//            .disposed(by: disposeBag)

        headerView.sectionButtonTappedClosure = { [weak self] (section, buttonType) in
            if buttonType == ButtonType.clearAll {
                self?.showClearAllConfirmationAlert(section: section, buttonType: buttonType)
            } else {
                self?.editAction(section: section, buttonType: buttonType)
            }
        }
        return headerView
    }

    func editAction(section: Int, buttonType: ButtonType) {

        var sections = self.dataSource.sectionModels
        let updateSection = (sections.count == 1 ? 0 : section)

        switch buttonType {
        /// Clear all
        case .clearAll:
            sections.remove(at: updateSection)
            let data = SectionedTableViewState(sections: sections)
            self.tableView.dataSource = nil
            Observable.of(data)
                .startWith(data) .map { $0.sections }
                .bind(to: tableView.rx.items(dataSource: dataSource))
                .disposed(by: disposeBag)
        /// Mark all as read
        case .markAllAsRead:
            if updateSection == 0 { sections = self.viewModel.getSections() }
            var items = sections[updateSection].items
            items = items.map { var unread = $0
                if $0.isUnRead == true { unread.isUnRead = false }
                return unread
            }
            sections.remove(at: updateSection)
            let allReadItems = sections[updateSection].items + items
            sections[updateSection] = TableDataSource(
                original: sections[updateSection],
                items: allReadItems)

            let data = SectionedTableViewState(sections: sections)
            self.tableView.dataSource = nil
            Observable.of(data)
                .startWith(data) .map { $0.sections }
                .bind(to: tableView.rx.items(dataSource: dataSource))
                .disposed(by: disposeBag)
        }
    }

    func showClearAllConfirmationAlert(section: Int, buttonType: ButtonType) {

        let alert = UIAlertController(title: "Clear All",
                                      message: "Are you sure, you want to clear all Items?",
                                      preferredStyle: .alert)

        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
            switch action.style{
            case .default:
                self.editAction(section: section, buttonType: buttonType)
            case .cancel: break
            case .destructive: break
            default:break
            }}))
        let cancel = UIAlertAction(title: "Cancel", style: .default, handler: { action in
        })
        alert.addAction(cancel)
        self.present(alert, animated: true, completion: nil)
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return sectionHeight
    }
}


类ViewController:UIViewController,可故事板{
@IBVAR表格视图:UITableView!
@IB出口弱var关闭按钮:UIButton!
@IBVAR标题文本:UILabel!
var viewModel:viewModel!
设disposeBag=disposeBag()
让截面高度:CGFloat=70
让dataSource=ViewController.dataSource()
重写func viewDidLoad(){
super.viewDidLoad()
}
覆盖函数视图将出现(uo动画:Bool){
超级。视图将显示(动画)
bindInitials()
bindDataSource()
bindDelete()
}
private func bindInitials(){
tableView.delegate=nil
tableView.rx.setDelegate(自身)
.处置(由:处置人)
registerNibs()
}
专用函数注册表项{
让headerNib=UINib.init(
nibName:TableViewSection.identifier,
捆绑:无)
tableView.register(
校长,
forHeaderFooterViewReuseIdentifier:TableViewSection.identifier)
}
}
扩展视图控制器:可绑定{
func bindViewModel(){
bindActions()
}
私有func bindDataSource(){
bindDelete()
//tableView.dataSource=nil
//可观察。仅(部分)
//.bind(到:tableView.rx.items(数据源:数据源))
//.处置(由:处置人)
}
私有函数bindDelete(){
///TODO:检查并更新删除代码以正常工作,使用“全部清除”并将所有标记为已读
guard let sections=self.viewModel?.getSections()else{
返回
}
让deleteState=SectionedTableViewState(节:节)
让deleteCommand=tableView.rx.itemDeleted.asObservable()
.map(TableViewEditingCommand.deleteSingle)
tableView.dataSource=nil
可观察的(删除命令)
.merge()
.scan(删除状态){
(状态:SectionedTableViewState,
命令:TableViewEditingCommand)->中的SectionedTableViewState
返回状态.execute(command:command)}
.startWith(deleteState).map{$0.0}
.bind(到:tableView.rx.items(数据源:数据源))
.处置(由:处置人)
}
私有函数bindActions(){
让openDetailsObserver=self.viewModel?.input.openDetailsObserver,
让closeObserver=self.viewModel?.input.closeObserver-else{
返回
}
viewModel.output.titleTextDriver
.drive(titleText.rx.text)
.处置(由:处置人)
//viewModel.input.dataSourceObserver
//.mapObserver({(结果)->[数据]位于
//返回结果
//            })
//.处置(由:处置人)
///使用closeObserver关闭按钮绑定
closeButton.rx.tap
.绑定(到:(观察者)
.处置(由:处置人)
///使用openDetailsObserver绑定选定的Tableview项
tableView.rx.itemSelected
.map{indexPath in
返回(self.dataSource[indexPath.section].items[indexPath.row])
}.subscribe(openDetailsObserver).disposed(由:disposeBag)
}
}
扩展视图控制器:UITableViewDelegate{
静态func dataSource()->rxtableviewsectionedanimatedatasource{
返回RxTableViewSectionedAnimatedDataSource(
animationConfiguration:animationConfiguration(插入动画:.fade,
重新加载动画:。淡入淡出,
删除动画:。淡入淡出),
configureCell:{(数据源、表、idxPath、项)位于
var cell=table.dequeueReusableCell(标识符为TableViewCell.identifier)作为TableViewCell
让cellViewModel=TableCellViewModel(withItem:item)
cell?.setViewModel(至:cellViewModel)
返回单元格??UITableViewCell()
},CaneditRowatineXpath:{{uu,{uu返回true})
}
func tableView(tableView:UITableView,viewForHeaderInSection:Int)->UIView{

class ViewModel {

    private enum Constants {
        static let titleText = "Test".localized
        static let testHistoryHeaderText = "test".localized
        static let unreadHeaderText = "Unread".localized
    }

    struct Input {
        let dataSourceObserver: AnyObserver<[Data]>
        let openDetailsObserver: AnyObserver<Data>
        let closeObserver: AnyObserver<Void>
        let sectionButtonTappedObserver: AnyObserver<IndexPath>
    }

    struct Output {
        let titleTextDriver: Driver<String>
        let dataSourceDriver: Driver<[Data]>
        let viewComplete: Observable<DataCoordinator.Event>
    }

    let input: Input
    let output: Output

    private let dataSourceSubject =  PublishSubject<[Data]>()
    private let closeSubject = PublishSubject<Void>()
    private let openDetailsSubject = BehaviorSubject<Data>(value:Data())
    private let sectionButtonTappedSubject = PublishSubject<IndexPath>()
    private let disposeBag = DisposeBag()

    init(withRepository repository: Repository) {
        input = Input(
            dataSourceObserver: dataSourceSubject.asObserver(),
            openDetailsObserver: openDetailsSubject.asObserver(),
            closeObserver: closeSubject.asObserver(), sectionButtonTappedObserver: sectionButtonTappedSubject.asObserver()
        )
        let closeEventObservable = closeSubject.asObservable().map { _ in
            return Coordinator.Event.goBack
        }
        let openDetailsEventObservable = openDetailsSubject.asObservable().map { _ in
            return Coordinator.Event.goToDetails
        }

        let viewCompleteObservable = Observable.merge(closeEventObservable, openDetailsEventObservable)

        let list = ViewModel.getData(repository: repository)

        output = Output(
            titleTextDriver: Observable.just(Constants.titleText).asDriver(onErrorJustReturn: Constants.titleText),
            dataSourceDriver: Observable.just(list).asDriver(onErrorJustReturn: list),
            viewComplete: viewCompleteObservable)


    }


    ///TODO: To be updated as per response after API integration
    static func getData(repository: Repository) -> [Data] {
        return repository.getData()
    }

    func getSections() -> [TableDataSource] {

        let List = ViewModel.getData(repository: Repository())

        let unread = list.filter { $0.isUnRead == true }
        let read = list.filter { $0.isUnRead == false }

        let headerText = String(format:Constants.unreadHeaderText, unread.count)

        let sections = [TableDataSource(
            header: headerText,
            items: unread,
            sectionViewModel: SectionViewModel(
                withHeader: headerText,
                buttonType: ButtonType.markAllAsRead.rawValue,
                items: unread)),
                        TableDataSource(
                            header: Constants.historyHeaderText,
                            items: read,
                            SectionViewModel: SectionViewModel(
                                withHeader: Constants.historyHeaderText,
                                buttonType: ButtonType.clearAll.rawValue,
                                items: read))]
        return sections
    }
}