我正在使用RxSwift
我的UIViewController
包含UICollectionView
。我试图在我的集合视图中添加一个标题,但从未调用过:
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath)
答案 0 :(得分:4)
我有同样的问题。解决它转移到RxCollectionViewSectionedReloadDataSource
此类型的数据源具有页眉/页脚。标准版RxCollectionViewReactiveArrayDataSource没有页眉/页脚。
即使在RxCocoa UICollectionView+Rx扩展名中,也以RxCollectionViewSectionedReloadDataSource为例。
示例:
let dataSource = RxCollectionViewSectionedReloadDataSource<SectionModel<String, Double>>()
let items = Observable.just([
SectionModel(model: "First section", items: [
1.0,
2.0,
3.0
]),
SectionModel(model: "Second section", items: [
1.0,
2.0,
3.0
]),
SectionModel(model: "Third section", items: [
1.0,
2.0,
3.0
])
])
dataSource.configureCell = { (dataSource, cv, indexPath, element) in
let cell = cv.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! NumberCell
cell.value?.text = "\(element) @ row \(indexPath.row)"
return cell
}
items
.bind(to: collectionView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
答案 1 :(得分:3)
经过很长一段时间搞清楚,我有一个完整的答案。关键部分取决于RxDataSources dataSource.configureCell 和 dataSource.supplementaryViewFactory。
您需要通过正常注册笔尖进行设置。要使集合视图显示它的标题,您需要定义标题大小。使用集合流布局允许您保留单元格内部可能具有的任何绑定,而不是覆盖Rx委托代理RxCocoa在内部使用。
在这个例子中,我有一个viewModel用于整个屏幕,它包含一个RxVariable,其中包含一个itemViewModel数组,用于集合视图中的每个项目。
使用RxSwift,RxDataSources和RxCocoa的头文件的UICollectionView:
var disposeBag: DisposeBag? = DisposeBag()
@IBOutlet weak var collectionView: UICollectionView!
let dataSource = RxCollectionViewSectionedReloadDataSource<SectionModel<String, ItemViewModel>>()
override func viewDidLoad() {
super.viewDidLoad()
registerHeaderCell()
registerCollectionViewCell()
setupLayout()
bindViewModelToCollectionView()
}
private func registerHeaderCell() {
let nib = UINib(nibName: "HeaderCell", bundle: nil)
collectionView.register(nib, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderReuseId")
}
private func registerCollectionViewCell() {
let nib = UINib(nibName:"CollectionViewCell", bundle: nil)
collectionView.register(nib, forCellWithReuseIdentifier: "CellReuseId")
}
private func setupLayout(){
let layout = UICollectionViewFlowLayout()
layout.headerReferenceSize = CGSize(width: UIScreen.main.bounds.width, height: 100)
collectionView.setCollectionViewLayout(layout, animated: false)
}
private func bindViewModelToCollectionView(){
dataSource.supplementaryViewFactory = {(dataSource, collectionView, kind, indexPath) -> UICollectionReusableView in
let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderReuseId", for: indexPath) as! HeaderCell
header.setup()
return header
}
dataSource.configureCell = {(datasource, collectionView, indexPath, itemViewModel) -> UICollectionViewCell in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CellReuseId", for: indexPath) as! CollectionViewCell
cell.setup()
return cell
}
viewModel.itemViewModels.asObservable().map {
(itemViewModels) -> [SectionModel<String, ItemViewModel>] in
//my particular app has one big section but you can use this for mutiple sections like Sergiy's answer
return [SectionModel(model: "", items: itemViewModels)]
}.bind(to: collectionView.rx.items(dataSource: dataSource))
.addDisposableTo(disposeBag!)
}
deinit {
disposeBag = nil
}
答案 2 :(得分:-3)
除非您使用RxDataSources
,否则与RxSwift
无关。
您无法正确设置UICollectionView
。除其他外:
func numberOfSections(in collectionView: UICollectionView) -> Int
以返回大于0
的内容。func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
以返回大于CGSize(width: 0, height: 0)
的尺寸。nib
,请将其注册为func register(_ nib: UINib?, forSupplementaryViewOfKind kind: String, withReuseIdentifier identifier: String)
。或者,如果您以编程方式创建它,请将其注册到func register(_ viewClass: AnyClass?, forSupplementaryViewOfKind elementKind: String, withReuseIdentifier identifier: String)
。