I am programmatically adding a UIButton to a custom UICollectionViewCell. Taps on the button are only detected if I do a long press on the cell first. Then the button works as expected. I have to do the same long press on each cell individually in order to get their respective button to recognize taps.
Note that single taps (i.e. didSelectItemAtIndexPath) on cells work as expected. So does long press on a cell. It might be worth noting that UILongPressGestureRecognizer is the only gesture added to the collectionView.
UICollectionViewCell class
- (UIButton *)stackInfoButton
{
if(_stackInfoButton == nil)
{
self.stackInfoButton = [UIButton buttonWithType:UIButtonTypeInfoDark];
[self.stackInfoButton setShowsTouchWhenHighlighted:YES];
}
return _stackInfoButton;
}
- (void)layoutSubviews
{
// Other stuff here. Removed for readability
self.stackInfoFrame = CGRectMake(4.0f, self.bounds.size.height - self.stackInfoButton.bounds.size.height - 4, self.stackInfoButton.bounds.size.width, self.stackInfoButton.bounds.size.height);
}
- (void)drawRect:(CGRect)rect
{
// Other stuff here. Removed for readability
self.stackInfoButton.frame = self.stackInfoFrame;
[[self contentView] addSubview:self.stackInfoButton];
}
UICollectionViewController class
- (void)viewDidLoad
{
[super viewDidLoad];
// Other stuff here. removed for readability
self.longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
self.longPressGesture.delegate = self;
[self.collectionView addGestureRecognizer:self.longPressGesture];
self.longPressGesture.cancelsTouchesInView = NO;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
DVCardViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kDVCollectionViewCellReuseIdentifier forIndexPath:indexPath];
cell.indexPath = indexPath;
// Other stuff here. Removed for readability
[cell.stackInfoButton addTarget:self action:@selector(stackInfoButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (void)stackInfoButtonTapped:(id)sender
{
NSLog(@">>> Entering %s <<<", __PRETTY_FUNCTION__);
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
NSLog (@"Touch View : %@", touch.view);
// tried both.
// DVCardViewCell *cell;
// if (touch.view == cell.stackInfoButton)
if ( [touch.view isKindOfClass:[UIButton class]] )
{
NSLog(@"Gesture on button, returns no");
return NO;
}
NSLog(@"Gesture returns outside, yes");
return YES;
}
Suggestions appreciated. I've been through many UICollectionView threads on SO. Yet to find one that addresses my issue. Thanks.