Search code examples
iosuiscrollviewuicollectionviewuicollectionviewcelluiresponder

why UICollectionView not calling didSelectItemAtIndexPath any more after scrolling the scrollView of it's cells?


I am using the UICollectionView to display some products. In the custom UICollectionViewCell, there is a custom UIScrollView, where there are some images which allow the users to do a quick preview.

To forward tap gesture from the UIScrollView to the UICollectionViewCell, i override the touches related methods as below:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging) {
        NSLog(@"Began ==>");
        [self.nextResponder touchesBegan:touches withEvent:event];
    }
    else {
        [super touchesBegan:touches withEvent:event];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging) {
        NSLog(@"Moved ==>");
        [self.nextResponder touchesMoved:touches withEvent:event];
    }
    else {
        [super touchesMoved:touches withEvent:event];
    }

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging) {
        NSLog(@"Ended ==>");
        [self.nextResponder touchesEnded:touches withEvent:event];
    }
    else {
        [super touchesEnded:touches withEvent:event];
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging) {
        NSLog(@"Cancelled ==>");
        [self.nextResponder touchesCancelled:touches withEvent:event];
    }
    else {
        [super touchesCancelled:touches withEvent:event];
    }
}

sometimes it doesn't work in some cases. For example, when the UICollectionView is loaded first time, didSelectItemAtIndexPath method can be called when you tap, but after some scrolls or taps, the method is not called anymore, even if you try to reload the UICollectionView, it's still not working.

I try to log the message in the touch methods of UICollectionViewCell, the touches & event is forwarded. But why the didSelectItemAtIndexPath of UICollectionView is called if the cell get the gesture?

Any advice would be much appreciated.

UPDATE: 1.the UICollectionViewCell is loaded from nib file.


Solution

  • Actually it's because of self.dragging understanding. The correct way to forward the tap gesture is as below:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self.nextResponder touchesBegan:touches withEvent:event];
    }
    
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self.nextResponder touchesMoved:touches withEvent:event];
    }
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        if (!self.dragging) {
            [self.nextResponder touchesEnded:touches withEvent:event];
        }
        else {
            [super touchesEnded:touches withEvent:event];
        }
    }
    
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self.nextResponder touchesCancelled:touches withEvent:event];
    }