我正在将RxSwift
与包含UIViewController
的UICollectionView
一起使用。我试图将 header 添加到我的收藏夹 View 中,但是从来没有这样称呼过:
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath)
最佳答案
经过长时间的研究,我得到了一个完整的答案。关键部分取决于RxDataSources dataSource.configureCell和dataSource.supplementaryViewFactory。
您将需要通过正常注册 Nib 进行设置。要使集合 View 显示其标题,您需要定义标题大小。使用收集流布局,可以保留Clickhandler单元内可能具有的所有绑定(bind),而不会覆盖RxCocoa在内部使用的rx委托(delegate)代理。
在此示例中,我为整个屏幕设置了一个viewModel,其中包含一个RxVariable以及用于集合 View 中每个项目的itemViewModels数组。
具有使用RxSwift,RxDataSources和RxCocoa的 header 的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: UICollectionView.elementKindSectionHeader, 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
}
关于ios - RxSwift和UICollectionView header ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39580085/