I have a UICollectionView
that horizontally scrolls to show one UICollectionViewCell
at a time. Each UICollectionViewCell
the has a vertically scrolling UIScrollView
as subview for scrolling the contents of the cell. It is only 90 % or so of the inner part of the UICollectionViewCell
that is covered by the UIScrollView
- i.e. the outer frame of the cell is not covered by this.
It turns out that the part of the UICollectionViewCell
that is covered by the UIScrollView
cancels the UICollectionView
delegate didSelectItemAtIndexPath
. Thus when a simple tap happens within the UIScrollView
this method is not invoked, whereas if the tap happens on the outer part of the cell, i.e. outside the UIScrollView
, this method is invoked.
Any suggestions as to how to achieve a setup where it is possible to invoke the didSelectItemAtIndexPath
method even when the tap happens within the UIScrollView
?
The tap on the
UIScrollView
is used to see whether scrolling should be done.You should catch the single tap on the UIScrollView itself and pass it on to the surrounding
UICollectionViewCell
.I found that the most effective approach is to steal the
panGestureRecognizer
, exposed byUIScrollView
and disableuserInteraction
on thescrollView
. That way, you get the behavior of the scrollview but maintain the interaction on the collection view. On yourUICollectionViewCell
subclass:This is a method Apple recommends and demonstrates in WWDC 2014 session 235 (Advanced Scrollviews and Touch Handling Techniques)
Add tap gesture to your super view
Here's a UIScrollView subclass approach that maintains cell selection functionality, and also allows for UIControl selection (buttons, etc) both in & outside of the scrollview.
Swift 3
Swift 2
Objective-C