从 UICollectionView 索引路径获取模型
Posted
技术标签:
【中文标题】从 UICollectionView 索引路径获取模型【英文标题】:Get model from UICollectionView indexpath 【发布时间】:2017-10-18 13:41:56 【问题描述】:我正在使用RxSwift
将模型数组绑定到集合视图
如何从给定的 indexPath 中获取模型对象?
我正在做这样的绑定:
vm.bikeIssueCatagories()
.drive(self.collectionView.rx.items(cellIdentifier: "BikeIssueCategoryCollectionViewCell", cellType: UICollectionViewCell.self)) row, data, cell in
.disposed(by: disposeBag)
我的问题的核心是,我需要同时获取模型对象和用户选择的单元格。使用 collectionView.rx.modelSelected(T.self)
只会给我模型 og 类型 T
。而调用collectionView.rx.itemSelected
只会给我选择的IndexPath
collectionView.rx.itemSelected.asDriver()
.driveNext [unowned self] indexPath in
guard let model = try? collectionView.rx.model(at: indexPath) else return
guard let cell = self.collectionView.cellForItem(at: indexPath) else return
.disposed(by: disposeBag)
但是当我尝试使用 indexPath 的模型时,这给了我一个错误:
类型“inout UICollectionView”不符合协议 '反应兼容'
只是尝试:
let indexPath = IndexPath.init()
self.collectionView.rx.model(at: indexPath)
也给了我一个错误:
对成员'model(at:)'的模糊引用
SO...如何同时获取模型对象和用户选择的单元格?
【问题讨论】:
【参考方案1】:我本可以像 RamwiseMatt 提议的那样做。在我的 ViewModel 上创建一个采用 IndexPath
并返回模型的方法。然而我最终还是使用了zip
:
let modelSelected = collectionView.rx.modelSelected(SelectableBikeIssueCategory.self).asObservable()
let cellSelected = collectionView.rx.itemSelected.asObservable()
.map [weak self] indexPath -> UICollectionViewCell in
guard let cell = self?.collectionView.cellForItem(at: indexPath) else fatalError("Expected cell at indexpath")
return cell
Observable.zip(cellSelected, modelSelected)
.map [weak self] cell, category -> SomeThing in
return SomeThing()
【讨论】:
【参考方案2】:你自己接受的解决方案不是最优的,因为modelSelected流在内部映射了indexPath,需要在不需要知道indexPath的时候使用。在您的情况下,最好使用 itemSelected 并转换为例如元组。
collectionView.rx.itemSelected
.map [weak self] indexPath in
guard
let model = try? self?.collectionView.rx.model(at: indexPath) as YourModelName?,
let cell = self?.collectionView.cellForItem(at: indexPath)
else
preconditionFailure("Describing of error")
return (cell, model)
【讨论】:
【参考方案3】:您的 ViewModel 定义了一个方法 bikeIssueCatagories()
,这是您的 UIViewController 将 UICollectionView 绑定到的方法。要将您的模型放在正确的位置,您可以使用您提到的itemSelected
属性,它会为您提供Observable<IndexPath>
,您应该将其输入到您的 ViewModel 中。在那里,您可以使用 IndexPath 的item
属性来确定您的数据数组(在bikeIssueCatagories()
中给出)中的哪个模型是您正在寻找的模型。 modelSelected
属性使您更容易做到这一点,因为它已经知道数据源,因此您只需提供模型的类型(将 T.self
替换为 YourModelName.self
。)
我不知道你为什么还要引用你的单元格,但如果你必须,你可以在你的UICollectionView
上使用cellForItem(at:)
(将你通过itemSelected
获得的IndexPath 提供给它。)
【讨论】:
以上是关于从 UICollectionView 索引路径获取模型的主要内容,如果未能解决你的问题,请参考以下文章
如何获取 uicollectionview 的最后一个索引路径?
使用点击手势时如何获取 UICollectionView 标头的索引路径?
UICollectionView接收具有不存在的索引路径的单元格的布局属性