I have a custom UICollectionViewCell
subclass that contains a UIScrollView
.
The scroll view scrolls correctly, however it intercepts taps, so that the collection view cell highlighting and selecting is not working as expected.
Setting userInteractionEnabled
to NO
allows taps "through" but scrolling doesn't work (of course).
Overriding hitTest:withEvent:
is no use as I need to know whether it's a tap or a pan before forwarding.
Any thoughts?
I ran into this today. Here's how I solved it, but there has to be a better way. I shouldn't have to put collection view selection logic into my cell code.
Add a UITapGestureRecognizer to the scroll view.
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewTapped:)];
[scrollView addGestureRecognizer:tapGesture];
Then, in the callback, you have to simulate what would happen on a normal tap on the cell:
-(void) scrollViewTapped:(UITapGestureRecognizer *)sender {
UIView *tappedView = [sender view];
while (![tappedView isKindOfClass:[UICollectionView class]]) {
tappedView = [tappedView superview];
}
if (tappedView) {
UICollectionView *collection = (UICollectionView *)tappedView;
NSIndexPath *ourIndex = [collection indexPathForCell:self];
BOOL isSelected = [[collection indexPathsForSelectedItems] containsObject:ourIndex];
if (!isSelected) {
BOOL shouldSelect = YES;
if ([collection.delegate respondsToSelector:@selector(collectionView:shouldSelectItemAtIndexPath:)]) {
shouldSelect = [collection.delegate collectionView:collection shouldSelectItemAtIndexPath:ourIndex];
}
if (shouldSelect) {
[collection selectItemAtIndexPath:ourIndex animated:NO scrollPosition:UICollectionViewScrollPositionNone];
if ([collection.delegate respondsToSelector:@selector(collectionView:didSelectItemAtIndexPath:)]) {
[collection.delegate collectionView:collection didSelectItemAtIndexPath:ourIndex];
}
}
} else {
BOOL shouldDeselect = YES;
if ([collection.delegate respondsToSelector:@selector(collectionView:shouldDeselectItemAtIndexPath:)]) {
shouldDeselect = [collection.delegate collectionView:collection shouldDeselectItemAtIndexPath:ourIndex];
}
if (shouldDeselect) {
[collection deselectItemAtIndexPath:ourIndex animated:NO];
if ([collection.delegate respondsToSelector:@selector(collectionView:didDeselectItemAtIndexPath:)]) {
[collection.delegate collectionView:collection didDeselectItemAtIndexPath:ourIndex];
}
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With