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?