在任何人将其复制之前,我已经在SO和其他站点上放置了所有RxDatasource标签。但是没有人为我工作。

因此,我的问题与this完全相关,我也针对该案例进行了追踪。但是我也不知道这里发生了什么。而这是两个星期的挣扎。我也检查了gitHub代码示例,但无法理解。
我已经在MVVM架构模式上使用RxSwiftRealm创建了一个应用程序,一切正常,但是现在我需要使用UICollectioView在视图中创建两个部分,因为我了解了RxdataSource并尝试应用它,但是我一无所获它实际上在做什么。我尝试创建其他项目来学习也没有用的项目。我仍然尝试并编写此代码,但它给了我错误。

我所做的就是从上面提供的链接中找到以下代码。我还不知道如何在拆分后为一个数组提供数据或列表中的数据。下面是我的整个代码。

我不知道这个方块在做什么。

//Changed
struct SectionViewModel {
    var header: String!
    var items: [StudentModel]
}

extension SectionViewModel: SectionModelType {
    typealias Item  = StudentModel
    init(original: SectionViewModel, items: [StudentModel]) {
        self = original
        self.items = items
    }
}

然后我的CollectionView类就像
class StudentCV: UIViewController, UICollectionViewDelegateFlowLayout {

    //MARK: - Outlets

    @IBOutlet weak var studentsView: UICollectionView!

    let studentCells = BehaviorRelay<[StudentModel]>(value: [])
    var notificationToken: NotificationToken? = nil

    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        let flowLayout = UICollectionViewFlowLayout()
        let size = CGSize(width: 105, height: 135)
        flowLayout.itemSize = size
        studentsView.setCollectionViewLayout(flowLayout, animated: true)
        studentsView.rx.setDelegate(self).disposed(by: disposeBag)

        setupBinding()
    }

    func studentLeft(value: Int, id: Int) {
        SignalRService.sharedClass.chatHub.invoke(method: "StudentLeft", withArgs: [id, value]){ (result, error) in
            if let e = error {
                print("Error: \(e)")
            } else {
                print("Done!")
                let vale = Database.singleton.updatePickupStatus(studentId: id, pickupValue: value)
                TestDebug.debugInfo(fileName: "", message: "STUDENT LEFTTT:: \(vale)")
                if let r = result {
                    print("Result: \(r)")
                }
            }
        }
    }

    deinit {
        notificationToken?.invalidate()
    }
    func setupBinding() {
        studentsView.register(UINib(nibName: "StudentCVCell", bundle: nil), forCellWithReuseIdentifier: "studentCV")

        //Cell creation Changed here..............................

           dataSource.configureCell = { (ds, cv, ip, item) in
            let cell = cv.dequeueReusableCell(withReuseIdentifier: "studentCV", for: ip) as! StudentCVCell
            cell.viewModel = item
            return cell
        }


            studentCells
                .asObservable()
                .debug("STudent View: ")
                .map({ SectionViewModel(header: "Pickups Arrived", items: $0 ) })
                .bind(to: studentsView.rx.items(dataSource: dataSource)) // now here it is giving me this error (Instance method 'items(dataSource:)' requires the types '[SectionViewModel]' and 'SectionViewModel' be equivalent)
                .disposed(by: disposeBag)


        // item selection with model details.
        Observable
        .zip(
            studentsView
            .rx
            .itemSelected,
            studentsView
            .rx
            .modelSelected(StudentModel.self))
            .bind { [weak self] indexPath, model in

                let cell = self?.studentsView.cellForItem(at: indexPath) as? StudentCVCell
                if (model.pickupStatus == 2) {
                    // updating view accordingly
                }

        }.disposed(by: disposeBag)
    }

和ViewModels看起来像这样。从我居住的地方。
class StudentCollectionViewViewModel {


    //MARK: Outlets
    let disposeBag = DisposeBag()
    var notificationToken : NotificationToken? = nil
    let studentCells = BehaviorRelay<[StudentModel]>(value: [])

    var studentCell : Observable<[StudentModel]> {
        return studentCells.asObservable()
    }


    deinit {
        notificationToken?.invalidate()
    }

    func getStudentsData(id: Int) {

        let studentsData = Database.singleton.fetchStudents(byCLassId: id)
        self.notificationToken = studentsData.observe{[weak self] change in
            TestDebug.debugInfo(fileName: "", message: "Switch:::: change")
            switch change {
            case .initial(let initial):
                TestDebug.debugInfo(fileName: "", message: "INIT: \(initial)")
                self!.studentCells.accept(Array(studentsData))
            case .update(_, let deletions, let insertions, let modifications):
                TestDebug.debugInfo(fileName: "", message: "MODIF::: \(modifications)")
                self!.studentCells.accept(Array(studentsData))
            case .error(let error):
                print(error)
            }
        }


    }

}

我正在从DB填充数据,但我需要创建两个列表,但我也无法到达必须发送两个数据列表才能填充的位置。另外,当我尝试在代码中使用它以查看工作原理时,它还会出现以下错误。
实例方法'items(dataSource :)'要求类型[[SectionModel]'和'[StudentModel]'是等效的
任何建议或帮助将不胜感激。提前致谢

最佳答案

RxCollectionViewSectionedReloadDataSource<SectionModel>期望您将绑定SectionModel类型的项目,因为您将SectionModel传递为通用参数。显然,您想使用StudentModel。为此,您可以使自己的StudentModel符合SectionModelType协议,然后使用RxCollectionViewSectionedReloadDataSource<StudentModel>:

extension StudentModel: SectionModelType {
    // implement
}

let dataSource = RxCollectionViewSectionedReloadDataSource<StudentModel>(configureCell: { (datasource, collectionView, indexPath, element) in
    // configure a cell
})
studentCells.bind(to: studentsView.rx.items(dataSource: dataSource))
    .disposed(by: disposeBag) // don't forget to setup disposal

但是我想StudentModel是描述单个单元格,而不是整个部分。在这种情况下,将StudentModel映射到SectionModel可能是一个更好的主意,如下所示:

let dataSource = RxCollectionViewSectionedReloadDataSource<SectionModel>(configureCell: { (datasource, collectionView, indexPath, element) in
    // configure a cell
})
studentCells
    .map { [SectionModel(model: "", items: $0)] }
    .bind(to: studentsView.rx.items(dataSource: dataSource))
    .disposed(by: disposeBag)

显然,我将所有studentCells映射到一个部分中,这可能不是您的情况。在更复杂的场景中,您可以考虑实现符合SectionModelType的自定义类型。

另外,您可以传递比空字符串更有价值的东西作为model,但这又取决于您的需要。

注意!
在上面的示例中,SectionModel代表RxDataSources.SectionModel,而不是:

enum SectionModel {
    case SectionOne(items: [SectionItem])
    case SectionTwo(items: [SectionItem])
}

关于ios - 如何使用RxDatasource在具有多个标题的UICollectionView中创建多个节,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58329578/

10-09 02:42