gpt4 book ai didi

ios - 如何使用 RxDatasource 在具有多个 header 的 UICollectionView 中创建多个部分

转载 作者:行者123 更新时间:2023-11-28 05:36:59 26 4
gpt4 key购买 nike

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

所以我的问题完全与this有关我也遵循了我的案例。但我也不知道这里发生了什么。这是两周的挣扎。我也检查了 gitHub 代码示例,但无法理解。我在 MVVM 架构模式上使用 RxSwiftRealm 创建了一个应用程序,一切正常,但现在我需要在我的 View 中创建两个部分为此使用 UICollectioView 我阅读了有关 RxdataSource 的内容并尝试应用它,但我完全不明白它实际上在做什么。我尝试创建其他学习项目,但这些项目也没有用。我仍然尝试编写此代码,但它给了我错误。

我所做的是从上面提供的链接在下面的代码中。我也不知道如何在拆分后为我的数据源提供来自一个数组的数据或列表。下面是我的全部代码。

我不知道这个 block 在做什么。

//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 看起来像这样。来 self 居住的地方。

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>期望您将绑定(bind) SectionModel 的项目输入,因为你通过了 SectionModel作为通用参数。显然,您想使用 StudentModel .为此,您可以制作 StudentModel符合 SectionModelType协议(protocol),然后使用 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 的自定义类型.

此外,您可以将比空字符串更有值(value)的内容作为 model 传递。 ,但这同样取决于您的需求。

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

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

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

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com