由于无法直接访问系统键盘视图[1],因此可能无法使用自定义UIGestureRecognizer
来测量触摸压力。如果使用自定义inputViewController
,则可以实现,但这对我来说不是一个选择。我想存储每个键的按键保持时间和按键压力。你知道这样做的方法吗?
编辑:[1]我说过“我们不能直接访问系统键盘的视图。”但实际上我们可以:
UIRemoteKeyboardWindow > InputSetContainerView > InputSetHostView
。
我认为,对Nirav Bhatt答案的改进可能会解决此问题,但会禁用键盘视图上的触摸功能。当我触摸按键时,它会输出触摸力,但相应的字母未在文本字段中键入。
答案 0 :(得分:3)
从iOS 9开始,作为UITouch has got force property的3D触摸的一部分,您可以完全获得在触摸事件期间施加的压力。
您可以将其与自定义视图实现结合在一起,每个字母数字字符作为UIButton接收触摸并将其传递。
更新:
经过UIWindow
的讨价还价,我终于能够在苹果的标准键盘窗口中捕获触摸事件。
诀窍是在hittest
扩展名中覆盖UIWindow
(也可以在UIView
级别上完成,但这会产生更广泛的含义,因为UIView
是{的祖先{1}}),并在看到UIWindow
发出的触摸时返回触摸处理对象。
UIRemoteKeyboardWindow
答案 1 :(得分:0)
解决方案比我想象的要容易。对于iOS 9+系统,我们可以按照以下步骤操作以访问系统键盘并听击键...
首先,创建一个自定义UIGestureRecognizer
来监听按键。由于该步骤很简单(只需覆盖touchesBegan
,touchesMoved
,touchesEnded
就可以了)。
添加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)
。
注意:您的手势识别器不应扩展UITapGestureRecognizer
。 UILongPressGestureRecognizer
可以。我们不能在视图中添加多个具有相同类型的轻击手势识别器。