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

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

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

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


当前回答

Swift解决方案将于2021年生效。对于这个解决方案,你不需要有对表视图的引用。

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    //return !(touch.view is UITableViewCell) <-- doesn't work, the type of the touched class is not UITableViewCell anymore
    
    var v = touch.view
    while v != nil {
        if v is UITableView { return false }
        v = v?.superview
    }
    return true
}

用法:

let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(YOUR_METHOD))
gestureRecognizer.delegate = self
YOUR_VIEW.addGestureRecognizer(gestureRecognizer)

其他回答

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

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来拥有一个包含这段代码的委托。

虽然现在已经很晚了,很多人发现上面的建议还不错,但我无法让Jason或TMilligan的方法起作用。

我有一个静态tableView与多个单元格包含文本字段接收数字输入只使用数字键盘。这对我来说很理想:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if(![touch.view isKindOfClass:[UITableViewCell class]]){

        [self.firstTF resignFirstResponder];
        [self.secondTF resignFirstResponder];
        [self.thirdTF resignFirstResponder];
        [self.fourthTF resignFirstResponder];

        NSLog(@"Touches Work ");

        return NO;
    }
    return YES;
}

确保你已经在你的.h文件中实现了<UIGestureRecognizerDelegate>。

这条线!view isKindOfClass:[UITableViewCell类]]检查tableViewCell是否被点击,并解散任何活动键盘。

这是我基于以上答案的解决方案… 这对我很有效……

//Create tap gesture for menu transparent view
UITapGestureRecognizer *rightTableTransparentViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(rightTableTransparentViewTapMethod:)];
[rightTableTransparentViewTap setCancelsTouchesInView:NO];
[_rightTableTransparentView addGestureRecognizer:rightTableTransparentViewTap];

- (void)rightTableTransparentViewTapMethod:(UITapGestureRecognizer *)recognizer {
    //Write your code here
}

我的情况是不同的,包括一个uisearchbar和uitableview在self.view。我想通过触摸视图来消除uisearchbar键盘。

var tapGestureRecognizer:UITapGestureRecognizer?

override func viewWillAppear(animated: Bool) {
    tapGestureRecognizer = UITapGestureRecognizer(target: self, action:Selector("handleTap:"))
}

关于UISearchBar委托方法:

func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool {
    view.addGestureRecognizer(tapGestureRecognizer!)
    return true
}
func searchBarShouldEndEditing(searchBar: UISearchBar) -> Bool {
    view.removeGestureRecognizer(tapGestureRecognizer!)
    return true
}

当用户触摸self.view时:

func handleTap(recognizer: UITapGestureRecognizer) {
    sampleSearchBar.endEditing(true)
    sampleSearchBar.resignFirstResponder()
}

Swift 5, 2020年5月。

当我输入文本时,我有一个textField和一个tableView。

初始状态 当我点击tableViewCell或其他东西时我想要2个不同的事件。

键盘和tableView显示出来了

首先我们添加tapGestureRecognizer。

tap = UITapGestureRecognizer(target: self, action: #selector(viewTapped))
tap.delegate = self
view.addGestureRecognizer(tap)

@objc func viewTapped() {
        view.endEditing(true)
}

然后我们将以下检查添加到UIGestureRecognizerDelegate中:

    extension StadtViewController: UIGestureRecognizerDelegate {
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if touch.view?.isDescendant(of: self.tableView) == true {
            return false
        } else {
            view.endEditing(true)
            return true
        }
    }
}

如果我想先隐藏键盘,tableView仍然是可见的,并对我的点击做出响应。

在这里输入图像描述