如何测量iOS系统键盘上的触摸压力(击键)?

时间:2018-08-07 12:01:57

标签: ios objective-c swift keystroke

由于无法直接访问系统键盘视图[1],因此可能无法使用自定义UIGestureRecognizer来测量触摸压力。如果使用自定义inputViewController,则可以实现,但这对我来说不是一个选择。我想存储每个键的按键保持时间和按键压力。你知道这样做的方法吗?

编辑:[1]我说过“我们不能直接访问系统键盘的视图。”但实际上我们可以: UIRemoteKeyboardWindow > InputSetContainerView > InputSetHostView

我认为,对Nirav Bhatt答案的改进可能会解决此问题,但会禁用键盘视图上的触摸功能。当我触摸按键时,它会输出触摸力,但相应的字母未在文本字段中键入。

2 个答案:

答案 0 :(得分:3)

从iOS 9开始,作为UITouch has got force property的3D触摸的一部分,您可以完全获得在触摸事件期间施加的压力。

您可以将其与自定义视图实现结合在一起,每个字母数字字符作为UIButton接收触摸并将其传递。

更新:

经过UIWindow的讨价还价,我终于能够在苹果的标准键盘窗口中捕获触摸事件。

诀窍是在hittest扩展名中覆盖UIWindow(也可以在UIView级别上完成,但这会产生更广泛的含义,因为UIView是{的祖先{1}}),并在看到UIWindow发出的触摸时返回触摸处理对象。

UIRemoteKeyboardWindow

答案 1 :(得分:0)

解决方案比我想象的要容易。对于iOS 9+系统,我们可以按照以下步骤操作以访问系统键盘并听击键...

首先,创建一个自定义UIGestureRecognizer来监听按键。由于该步骤很简单(只需覆盖touchesBegantouchesMovedtouchesEnded就可以了)。

添加KeyboardManager以访问键盘视图:

final class KeyboardManager {

    static let shared = KeyboardManager()

    private init() { }

    /// Returns keyboard view on application window
    ///
    /// - Returns: Keyboard view
    func keyboardView() -> UIView? {
        for window in UIApplication.shared.windows {
            if let keyboardView = keyboardViewFromWindow(window) {
                return keyboardView
            }
        }
        return nil
    }

    /// Returns keyboard view from given window
    ///
    /// - Parameter window: Keyboard view container candidate window
    /// - Returns: Keyboard view
    func keyboardViewFromWindow(_ window: UIWindow) -> UIView? {
        if window.hasClassNameSuffix("UIRemoteKeyboardWindow") {
            let inputSetContainerView = window.subview(withSuffix: "InputSetContainerView")
            let inputSetHostView = inputSetContainerView?.subview(withSuffix: "InputSetHostView")
            return inputSetHostView
        }

        return nil
    }
}
上面使用的

UIView扩展功能:

@nonobjc extension UIView {

    /// Returns first found subview with given class name
    ///
    /// - Parameter className: Subview class name
    /// - Returns: First subview with given class name
    func subview(withSuffix className: String) -> UIView? {
        return subviews.first {
            $0.hasClassNameSuffix(className)
        }
    }

    /// Compares suffix of view class name with given name
    ///
    /// - Parameter className: Class name that will be compared
    /// - Returns: Comparison result of view class name and given name
    func hasClassNameSuffix(_ className: String) -> Bool {
        return NSStringFromClass(type(of: self)).hasSuffix(className)
    }
}

然后,使用以下功能将手势识别器添加到键盘视图:

KeyboardManager.shared.keyboardView()?.addGestureRecognizer(keyboardGestureRecognizer)

注意:您的手势识别器不应扩展UITapGestureRecognizerUILongPressGestureRecognizer可以。我们不能在视图中添加多个具有相同类型的轻击手势识别器。