I'm writing a tiny image viewer based on UICollectionView and RxSwift/RxCocoa to provide delegation stuff. My goal is to make it possible to jump to a certain cell right after data is loaded from viewModel. Here is what I've tried so far.
ViewModel:
class ImageViewerViewModel {
let dataSource = BehaviorRelay<[UIImage]>(value: [])
let selectedImageIndex = BehaviorSubject<Int>(value: 0)
private let disposeBag = DisposeBag()
init(imageCollection: [UIImage], selectedIndex: Int) {
var newEntries = [UIImage]()
newEntries.append(contentsOf: imageCollection)
dataSource.accept(newEntries)
selectedImageIndex.onNext(selectedIndex)
}
}
ViewController:
class ImageViewerViewController: UIViewController, UIScrollViewDelegate {
private func setUpBindings() {
guard let viewModel = viewModel else { return }
viewModel.selectedImageIndex
.subscribe(onNext: { [weak self] selectedImageIndex in
// expect UICollectionView already loaded its data but it raises out-of-bounds exception instead
self?.collectionView.scrollToItem(at: IndexPath(row: selectedImageIndex, section: 0), at: .left, animated: false)
})
.disposed(by: disposeBag)
collectionView.rx.setDelegate(self)
.disposed(by: disposeBag)
viewModel.dataSource
.bind(to: collectionView.rx.items) { [weak self]
(collectionView: UICollectionView, row: Int, image: UIImage) in
// returns UICollectionViewCell
}
.disposed(by: disposeBag)
}
}
I expected that after calling dataSource.accept
method UICollectionView
stored data somewhere internally (like it works with collectionView.reloadData
) and we can programmatically scroll to certain cell. It appears that's not so.
collectionView.scrollToItem
causes exception
Attempted to scroll the collection view to an out-of-bounds item (1) when there are only 0 items in section 0
How can I subscribe on some sort of onDataLoaded
observable?