ios - 使用 RxDatasources 实现多个部分

标签 ios swift rx-swift rx-cocoa rxdatasources

我正在尝试使用 RxDatasources 制作多个部分(实际上是两个部分)。通常对于一个部分,我会这样:

剖面模型:

import Foundation

import RxDataSources

typealias NotificationSectionModel = AnimatableSectionModel<String, NotificationCellModel>


struct NotificationCellModel : Equatable, IdentifiableType {
    
    static func == (lhs: NotificationCellModel, rhs: NotificationCellModel) -> Bool {
        
        return lhs.model.id == rhs.model.id
    }
    
    var identity: String {
        return model.id
    }
    var model: NotificationModel
    var cellIdentifier = "NotificationTableViewCell"
}

然后是实际模型:

struct NotificationModel: Codable, Equatable {
    let body: String
    let title:String
    let id:String
}

我会像这样使用它(在 View Controller 中):

private func observeTableView(){
        let dataSource = RxTableViewSectionedAnimatedDataSource<NotificationSectionModel>(
            configureCell: { dataSource, tableView, indexPath, item in
                if let cell = tableView.dequeueReusableCell(withIdentifier: item.cellIdentifier, for: indexPath) as? BaseTableViewCell{
                    cell.setup(data: item.model)
                    
                    return cell
                }
                return UITableViewCell()
            })
        
        notificationsViewModel.notifications
            .map{ notifications -> [NotificationCellModel] in
                return notifications.map{ NotificationCellModel( model: $0, cellIdentifier: NotificationTableViewCell.identifier) }
            }.map{ [NotificationSectionModel(model: "", items: $0)] }
            .bind(to: self.tableView.rx.items(dataSource: dataSource)).disposed(by: disposeBag)
    }

但是我如何处理具有不同类型的模型/单元的多个部分?

最佳答案

这是一种最坏的情况。您也许可以根据您的用例简化此代码:

// MARK: Model Code
struct ViewModel {
    let sections: Observable<[SectionModel]>
}

typealias SectionModel = AnimatableSectionModel<String, CellModel>

enum CellModel: IdentifiableType, Equatable {
    case typeA(TypeAInfo)
    case typeB(TypeBInfo)
    
    var identity: Int {
        switch self {
        case let .typeA(value):
            return value.identity
        case let .typeB(value):
            return value.identity
        }
    }
    
    var cellIdentifier: String {
        switch self {
        case .typeA:
            return "TypeA"
        case .typeB:
            return "TypeB"
        }
    }
}

struct TypeAInfo: IdentifiableType, Equatable {
    let identity: Int
}

struct TypeBInfo: IdentifiableType, Equatable {
    let identity: Int
}

// MARK: View Code
class Example: UIViewController {
    var tableView: UITableView!
    var viewModel: ViewModel!
    let disposeBag = DisposeBag()
    
    private func observeTableView(){
        let dataSource = RxTableViewSectionedAnimatedDataSource<SectionModel>(
            configureCell: { _, tableView, indexPath, item in
                guard let cell = tableView.dequeueReusableCell(withIdentifier: item.cellIdentifier, for: indexPath) as? BaseCell else { fatalError() }
                cell.setup(model: item)
                return cell
            })
        
        viewModel.sections
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)
    }
}

class BaseCell: UITableViewCell {
    func setup(model: CellModel) { }
}
final class TypeACell: BaseCell { }
final class TypeBCell: BaseCell { }

关于ios - 使用 RxDatasources 实现多个部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70383010/

相关文章:

ios - 如何禁用 View Controller 的无限循环?

swift - 使用 RxSwift 链接操作

ios - 运行 iOS 项目时链接器错误

iphone - 指针困惑

ios - 一次显示和控制 2 个 View

swift - UITextview 上的 RxSwift

ios - 在 RxSwift 中测试 BehaviorSubject/Relay

objective-c - 启动画面期间的 UIAlert

ios - CoreData 完成后 Swift iOS 9 UITableView 重新加载数据

ios - 导致 "Cannot pass immutable as inout"的 Swift 3 转换