RxSwiftCommunity / RxDataSources

UITableView and UICollectionView Data Sources for RxSwift (sections, animated updates, editing ...)
MIT License
3.07k stars 489 forks source link

Error when using a collectionView with a custom UICollectionViewLayout. #241

Open jdisho opened 6 years ago

jdisho commented 6 years ago

Hi 👋

I have created a custom UICollectionViewLayout.

protocol PinterestLayoutDelegate: class {
    func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat
}

class PinterestLayout: UICollectionViewLayout {

    // MARK: Delegate
    weak var delegate: PinterestLayoutDelegate!

    // MARK: Overrides
    override var collectionViewContentSize: CGSize {
        ...
    }

    override func prepare() {
        ...
    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        ...
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        ...
    }
}

Then in a ViewController I am configuring a collectionView with the PinterestLayout and also the dataSource, as following:


override func viewDidLoad() {
        super.viewDidLoad()

         viewModel.searchPhotosCellModel
            .map { [SearchPhotosSectionModel(model: "", items: $0)] }
            .bind(to: collectionView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)
    }

...

private func configureCollectionView() {
        collectionView = UICollectionView(frame: view.frame, collectionViewLayout: PinterestLayout())
        view.addSubview(collectionView)
        collectionView.registerCell(type: SearchPhotosCell.self)
        dataSource = RxCollectionViewSectionedReloadDataSource<SearchPhotosSectionModel>(
            configureCell:  collectionViewDataSource
        )
    }

private var collectionViewDataSource: CollectionViewSectionedDataSource<SearchPhotosSectionModel>.ConfigureCell {
        return { _, collectionView, indexPath, cellModel in
            var cell = collectionView.dequeueReusableCell(
                type: SearchPhotosCell.self,
                forIndexPath: indexPath)
            cell.bind(to: cellModel)
            return cell
        }
    }

The problem that I am occurring when I am running the app is that I get the following error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for number of items in section 0 when there are only 0 sections in the collection view

I think this issue is related to RxDataSource underlying implementation. However, if you think it is not, it would be very helpful to show an example how to use this library with custom UICollectionViewLayout-s. 😊

Vkt0r commented 6 years ago

@jdisho It would be helpful to see an example of your project 🤔. Maybe It can be an issue in the library, but I have custom layouts implemented in some UICollectionViews and I don't have any issue with the library.

freak4pc commented 5 years ago

Hey @jdisho - Did you work this out? If not, as @Vkt0r mentioned, a project would be very helpful.

jdisho commented 5 years ago

Hey @freak4pc - Thanks for reminding me.

jdisho commented 5 years ago

Have a look at Papr @freak4pc

SearchPhoto is responsible group. To replicate the crash, go to Search -> search something -> Photos with "..."

mkko commented 5 years ago

What environment are you using? I tried but couldn't reproduce the crash with Xcode Version 9.4.1 (9F2000) and iPhone X Simulator with 11.4, on High Sierra.

freak4pc commented 5 years ago

Can't repro as well on Mojave Xcode 9.4.1

jdisho commented 5 years ago

Are you in rxdatasources-not-working branch?

freak4pc commented 5 years ago

You didn't mention a branch ;-)

jdisho commented 5 years ago

Sorry for the confusion. However, the link is with that branch 😄

mkko commented 5 years ago

The link directed to that branch. For some reason I still managed to download the -dev branch version.

mkko commented 5 years ago

Is this it?

        for item in 0..<collectionView.numberOfItems(inSection: 0) {

Line 54 in your new layout, PinterestLayout.

jdisho commented 5 years ago

Yes it is, but I don't expect 0 sections. Probably I am missing something from RxDataSources

mkko commented 5 years ago

It looked like the whole observable sequence didn't even start yet, so this seems to happen before the items are in the collection view. If you add .debug() to the sequence where you do the binding, there's no output before it crashes because of the layout.

jdisho commented 5 years ago

You are right, but how is the normal flow layout is handling this then?! 🤔

bordoli commented 5 years ago

In your prepare() implementation add a check of numberOfSections

guard cache.isEmpty == true,
    let collectionView = collectionView,
    collectionView.numberOfSections > 0 else { return }

😀

User2004 commented 5 years ago

Click here for set custom collection view flow layout i objective C

Click here for set custom collection cell in collectionview in swift

168-7cm commented 1 year ago

@bordoli sorry for mentioning you🙏 why we should check numberOfSections > 0?