我有一个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时,我都可以看到上面打印在控制台上的消息。但是,键盘不再出现。
我发现苹果的文档在这里令人困惑:这里,上面写着
手势识别器不参与视图的响应程序链条
我将其解释为,任何手势也会像正常情况一样发送到视图和链上。
后来在同一页上,它说,
如果手势识别器识别出其手势,则剩余的触摸视图的取消。
这意味着,如果附加的手势识别器能够将手势理解为它应该识别的手势,那么它将阻止将其传递到它所附加的视图。此外,它指定了3个属性,这些属性应该能够阻止手势识别器这样做。如上所示,我已经在代码中将这三个值都设置为false。
这里实际发生了什么?我如何允许UITextView正常解释触摸,并能够使用手势识别器?
您可以使用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
}
}
UITextView可能有自己的专用手势识别器来处理用户点击它时的情况。当这种情况发生时,它会使文本视图成为第一个响应程序,从而导致键盘出现。手势识别器可以迫使其他手势识别器在识别其手势时失败。(请参阅文档)也许这就是添加敲击手势时发生的情况。它识别敲击,从而迫使其他手势失败,从而阻止文本视图成为第一响应者。
最好的解决方案是遵循这个问题的答案(正如@FrancescoDeliro在评论中提到的那样),并使用代理调用来了解编辑何时开始/结束。