Reputation: 4352
I am trying to respond to UICollectionViewCell
selection:
private func setupCellAction() {
collectionView?.rx.itemSelected
.asObservable()
.subscribe(onNext: { [weak self] indexPath in
print("itemSelected!")
let cell = self?.collectionView?.cellForItem(at: indexPath) as? CellTypeCollectionViewCell
self?.performSegue(withIdentifier: "showBarchartSegue", sender: cell)
}).disposed(by: disposeBag)
}
But somehow onNext
method is never called. I tried putting setupCellAction()
in viewDidLoad
, viewWillAppear
and viewDidAppear
but it is not working. Any suggestions would be greatly appreciated.
Update
I tried the suggestion from the following thread: How to select CollectionView cell in RxSwift
and added .debug("RX: Model selected")
before the subscribe
method. I see the output in the console that it is subscribed once.
Update
I tried rewriting the setupCellAction()
in the following way:
private func setupCellAction() {
collectionView?.rx.modelSelected(CellTypeCollectionViewCell.self)
.asObservable()
.debug("RX: Model selected")
.subscribe(onNext: { [weak self] cell in
print("itemSelected!")
self?.performSegue(withIdentifier: "showBarchartSegue", sender: cell)
}).disposed(by: disposeBag)
}
It is not working either. I see also that it is subscribed once in the console.
Update
UICollectionViewController
was embedded in another container UIViewController
, and in it I defined UITapGestureRecognizer
. After commenting out the code for the UITapGestureRecognizer
, the itemSelected()
method started to work. Right now I need a way to let the tap event through if it happened on the UICollectionViewCell
. Is there a way to do that?
The code for tapping in the container controller (viewDidLoad
):
let tap = UITapGestureRecognizer(target: self, action:
#selector(self.handleTap(_:)))
tap.delegate = self
view.addGestureRecognizer(tap)
The handleTap():
@objc func handleTap(_ sender: UITapGestureRecognizer) {
tableView.isHidden = true
searchBar.resignFirstResponder()
}
Upvotes: 0
Views: 1259
Reputation: 66
You can let taps through with the UIGestureRecognizerDelegate protocol and implementing the method
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
.
Basically, you need to return false
whenever you touch a UICollectionViewCell
, if I understood the problem correctly.
You can do this by using the method func indexPathForItem(at point: CGPoint) -> IndexPath?
from the UICollectionView. If the given CGPoint matches a cell's location, you will get its IndexPath.
Don't forget to translate the touch location to the collection view's frame - you can use UITouch's func location(in view: UIView?) -> CGPoint
for this.
It would probably look somewhat like this:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
let point = touch.location(in: collectionView)
return collectionView.indexPathForItem(at: point) == nil
}
Upvotes: 5