CollectionView单元格上的按钮仅在长按后接收轻击

时间:2015-04-18 16:08:16

标签: ios objective-c uibutton uicollectionview uigesturerecognizer

我正在以编程方式将UIButton添加到自定义UICollectionViewCell。仅当我首先长按单元格时,才会检测到按钮上的点击。然后按钮按预期工作。我必须分别对每个单元格进行相同的长按,以便让各自的按钮识别水龙头。

请注意,单元格上的单击(即didSelectItemAtIndexPath)按预期工作。长按一个细胞也是如此。值得注意的是,UILongPressGestureRecognizer是添加到collectionView的唯一手势。

UICollectionViewCell类

- (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类

- (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;
}

建议表示赞赏。我在SO上经历了很多UICollectionView线程。然而,找到一个解决我的问题。感谢。

2 个答案:

答案 0 :(得分:0)

你说你已经在集合视图中添加了一个手势,所以你需要教这个手势,不要偷走它不应该参与的触摸。将控制器添加为手势的委托并实施gestureRecognizer:shouldReceiveTouch:。在该方法中,检查触摸点击的视图,如果是按钮,则返回NO以防止手势参与。

答案 1 :(得分:0)

试试这个

self.LongPressGesture.cancelsTouchesInView = NO;

抱歉错了。没关系。

这看起来很奇怪:

- (UIButton *)stackInfoButton
{
   if(_stackInfoButton == nil)
   {
      self.stackInfoButton = [UIButton buttonWithType:UIButtonTypeInfoDark]; // theoretically your app should crash now
      [self.stackInfoButton setShowsTouchWhenHighlighted:YES];
   }
   return _stackInfoButton;
 }

查看self.stackInfoButton = [UIButton buttonWithType:UIButtonTypeInfoDark];

一定是

 _stackInfoButton = [UIButton buttonWithType:UIButtonTypeInfoDark];
 [_stackInfoButton setShowsTouchWhenHighlighted:YES];

也许有帮助。