17

I need to select the item at specific index in collection view using RxSwift.This method is not working fine.

 collectionView.rx.modelSelected(SearchResult.self).subscribe(onNext:{ menuItem in }).addDisposableTo(disposeBag) 

Can anybody help?

Mehreen
  • 501
  • 3
  • 6
  • 11
  • Where are you declaring the disposeBag? – xandrefreire Apr 10 '17 at 15:17
  • Outside the ViewDidLoad() – Mehreen Apr 11 '17 at 09:48
  • When you say it is "not working fine" what does that mean? Does anything happen? If so, what happens? -- Have you checked via breakpoint if `menuItem` had the correct value based on what cell you clicked? – dsapalo Apr 12 '17 at 17:39
  • You can try debugging it using the `debug` operator - just add before the `.subscribe` this: `.debug("RX: Model selected")` and see whats going on behind the scene (is it being subscribed? maybe more then once? maybe its being disposed before it has the chance to emit anything) – goldengil Jul 23 '17 at 10:39
  • According to the RxCocoa docs `modelSelected(:)` can only be used if the table is populated using one of the `rx.items` overloads. Are you using one of those overloads? Another thing to check is that the table's delegate isn't being set in your code. – Paul Nov 21 '18 at 10:44

2 Answers2

38

If you want the indexPath of item selected you can use the following :

collectionView
    .rx
    .itemSelected
        .subscribe(onNext:{ indexPath in
            //your code
        }).disposed(by: disposeBag)

and if you want to the model being selected :

collectionView
        .rx
        .modelSelected(SearchResult.self)
        .subscribe(onNext: { (model) in
            //Your code
        }).disposed(by: disposeBag)

And you can combine the above, to get the modelSelected with their indexPath as follow:

  Observable
            .zip(
                collectionView
                    .rx
                    .itemSelected
                ,collectionView
                    .rx
                    .modelSelected(SearchResult.self)
            )
            .bind{ [unowned self] indexPath, model in

            }
            .disposed(by: disposeBag)
    }
mojtaba al moussawi
  • 1,360
  • 1
  • 13
  • 21
3

Building off of mojtaba al moussawi's answer, I made an extension to make the zipping easy:

extension Reactive where Base: UICollectionView {
    public func modelAndIndexSelected<T>(_ modelType: T.Type) -> ControlEvent<(T, IndexPath)> {
        ControlEvent(events: Observable.zip(
            self.modelSelected(modelType),
            self.itemSelected
        ))
    }
}

Which you would use like:

collectionView
    .rx
    .modelAndIndexSelected(SearchResult.self)
    .subscribe(onNext: { (model, index) in
        //Your code
    }).disposed(by: disposeBag)
Greg
  • 41
  • 1
  • 2