使用水龙头关闭 UIKeyboard 时如何忽略所有 UIControl 水龙头

How to ignore all UIControl Taps, when using the tap to close UIKeyboard

这个问题源于我之前的问题

所以当用户有键盘时,我希望用户能够点击键盘或 UITextView 以外的任何地方来关闭键盘。这行得通...但我也希望 "first" 点击关闭键盘不会引起任何其他操作。

UIKeyboard 存在...用户点击任意位置关闭并碰巧点击 UIButtonUIKeyboard 已关闭,UIButton 的操作未发送。


我尝试放置

@IBAction func blahblah(sender: UIButton){
    if keyboardShow == false {//UIButtons action here
    }
}

但是在一些 println() 测试中,显示在 UIButton 注册点击之前键盘已关闭(因此 keyboardShow 设置为 false)。

But I also want that "first" tap that closes the keyboard to not cause any other actions.

您可以按您现在的方式进行操作,但这样做非常不灵活,因为您必须分别单独处理所有其他控件。

最简单的方法就是在整个 "screen" 之上放置一个不可见的视图(即,将其添加到视图控制器的视图中,在所有视图的前面)——除了它应该在文本视图后面。

text view
secret invisible view
all other views (buttons etc.)

通常,您的秘密不可见视图的 userInteractionEnabledfalse,因此点击只会落到它后面的任何地方,就好像不可见视图根本不存在一样。用户可以点击按钮等。

但是当你显示键盘时,你也将你的秘密不可见视图的 userInteractionEnabled 设置为 true 并给它一个点击手势识别器。因此,当用户在文本视图外点击时,点击手势识别器会做出响应,然后您关闭键盘。

当您关闭键盘时,所有这些都将反转:删除点击手势识别器并将不可见视图的 userInteractionEnabled 变为 false

我一直在我的应用程序中使用这种技巧。

也可以更复杂:将干扰的不可见视图放在 所有内容 前面并覆盖其触摸处理 (hitTest:)。这是一个阻止所有触摸的视图示例,除了会落在位于 后面 :

的一个特定 passthruView 上的触摸
class BlockerView: UIView {
    weak var passthruView : UIView!
    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        if let pv = self.passthruView {
            let pt = pv.convertPoint(point, fromView: self)
            if pv.pointInside(pt, withEvent: event) {
                return nil // let the touch fall thru
            }
        }
        return super.hitTest(point, withEvent: event)
    }
}