我已经编写了自己的函数,当键盘出现时滚动文本字段。为了通过点击离开文本字段来取消键盘,我创建了一个UITapGestureRecognizer,它负责在点击离开时放弃文本字段上的第一个响应器。

现在我还为文本字段创建了一个自动完成,它在文本字段的下面创建了一个UITableView,并在用户输入文本时用项目填充它。

但是,当选择自动补全表中的一个条目时,不会调用didSelectRowAtIndexPath。相反,它似乎是点击手势识别器被调用,只是辞职第一响应器。

我猜有一些方法告诉点击手势识别器继续将点击消息传递给UITableView,但我不知道它是什么。任何帮助都将不胜感激。


当前回答

好的,在搜索手势识别器文档后终于找到了。

解决方案是实现UIGestureRecognizerDelegate并添加以下内容:

#pragma mark UIGestureRecognizerDelegate methods
    
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
  if ([touch.view isDescendantOfView:autocompleteTableView]) {
            
    // Don't let selections of auto-complete entries fire the 
    // gesture recognizer
    return NO;
  }
        
  return YES;
}

这样就解决了。希望这也能帮助到其他人。

其他回答

问题: 在我的例子中,问题是我最初在每个collectionView单元格中放置了一个按钮,并设置了填充单元格的约束,这样当单击单元格时,它就会单击按钮,然而按钮函数是空的,因此似乎什么都没有发生。

解决办法: 我通过从集合视图单元格中删除按钮来解决这个问题。

为UIGestureRecognizer的委托实现这个方法:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
       shouldReceiveTouch:(UITouch *)touch
{
  UIView *superview = touch.view;
  do {
    superview = superview.superview;
    if ([superview isKindOfClass:[UITableViewCell class]])
      return NO;
  } while (superview && ![superview isKindOfClass:[UITableView class]]);

  return superview != nil;
}

解决这个问题最简单的方法是:

UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc] 
    initWithTarget:self action:@selector(tap:)];
[tapRec setCancelsTouchesInView:NO];

这让UIGestureRecognizer识别点击,并将触摸传递给下一个响应器。这个方法的一个意想不到的结果是,如果你在屏幕上有一个UITableViewCell来推另一个视图控制器。如果用户轻按该行以取消键盘,则键盘和推送都将被识别。我怀疑这是你的意图,但这种方法适用于许多情况。

同时,扩展Robert的回答,如果你有一个指向表视图的指针,那么你可以直接比较它的类,而不是必须转换为字符串,希望苹果不会改变命名法:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
     shouldReceiveTouch:(UITouch *)touch
{
    if([touch.view class] == tableview.class){
        return //YES/NO
    }

    return //YES/NO

}

记住,你还必须声明UIGestureRecognizer来拥有一个包含这段代码的委托。

在swift中,您可以在内部使用此功能

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if CheckTheTime() == true {
        // do something 
    }else{
    }
}

func CheckTheTime() -> Bool{
    return true
}

斯威夫特(根据@Jason的回答):

class MyAwesomeClass: UIViewController, UIGestureRecognizerDelegate

private var tap: UITapGestureRecognizer!

override func viewDidLoad() {
   super.viewDidLoad()

   self.tap = UITapGestureRecognizer(target: self, action: "viewTapped:")
   self.tap.delegate = self
   self.view.addGestureRecognizer(self.tap)
}

// UIGestureRecognizerDelegate method
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    if touch.view?.isDescendantOfView(self.tableView) == true {
        return false
    }
    return true
}