UITextView的UIGestureRecognizer防止在点击时出现键盘

时间:2019-01-19 16:49:49

标签: ios swift event-handling uitextview uigesturerecognizer

我有一个UITextView,下面已附加了一个手势识别器:

let testTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(textTextViewTapped(gestureRecognizer:)))
testTapGestureRecognizer.cancelsTouchesInView = false
testTapGestureRecognizer.delaysTouchesBegan = false
testTapGestureRecognizer.delaysTouchesEnded = false
if textTextView != nil {
    textTextView!.addGestureRecognizer(testTapGestureRecognizer)
}

上述选择器如下:

@objc func textTextViewTapped(gestureRecognizer: UIGestureRecognizer) {
    print("testTextViewTapped called.")
}

每次我点击UITextView时,都可以在控制台上看到上面的消息。但是,键盘不再显示。

我在这里发现Apple的文档令人困惑: Here表示

  

手势识别器未参与视图的响应器   链。

我将其解释为,所有手势也会像往常一样发送到视图和上链。

稍后在同一页面上说

  

如果手势识别器识别出其手势,则剩余的触摸   该视图被取消。

这意味着,如果附加的手势识别器能够将手势理解为应该识别的手势,则它将阻止将其传递到附加的视图。此外,它指定了3个应该可以阻止手势识别器执行此操作的属性。如上所示,我已在代码中将它们全部设置为false。

这里实际发生了什么?如何允许UITextView正常解释触摸并能够使用手势识别器?

2 个答案:

答案 0 :(得分:1)

UITextView可能具有自己的专用手势识别器,以在用户点击它时进行处理。发生这种情况时,它将使文本视图成为第一响应者,这将导致键盘出现。手势识别器可以强制其他手势识别器在识别出自己的手势时失败。 (请参阅getLineTop())也许这就是您添加轻敲手势时发生的情况。它可以识别轻击,从而迫使其他手势失败,从而阻止了文本视图成为第一响应者。

最好的解决方案是遵循docs的回答(@FrancescoDeliro在评论中提到),并使用委托调用来知道何时开始/结束编辑。

答案 1 :(得分:1)

您可以使用UIGestureRecognizerDelegate使UITapGestureRecognizer遵循常规的UITextView行为:

class TestViewController: UIViewController {

    @IBOutlet weak var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tap))
        tapGestureRecognizer.delegate = self

        textView.addGestureRecognizer(tapGestureRecognizer)
    }

    @objc private func tap() {
        print("tap")
    }

}

extension TestViewController: UIGestureRecognizerDelegate {

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }

}