使用自定义UIGestureRecognizer可能无法测量触摸压力,因为我们不能直接访问系统键盘的视图1。如果使用自定义inputViewController,它可以实现,但对我来说不是选项。我想存储键保持时间和每个键的按键压力。你知道怎么做吗?
编辑:1我说:“我们不能直接访问系统键盘的视图。”但实际上我们可以:UIRemoteKeyboardWindow > InputSetContainerView > InputSetHostView。
我认为,对Nirav的回答进行改进可以解决这个问题,但它禁用了键盘视图上的触摸功能。当我触摸一个键时,它输出触摸的力量,但是相应的字母没有被输入到文本字段。
发布于 2018-08-21 09:08:05
解决办法比我想的要容易。对于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没事。不能向视图中添加具有相同类型的多个抽头手势识别器。
发布于 2018-08-08 08:03:26
从iOS 9开始,作为3D触摸的一部分,UITouch有力性质给你提供了在触摸事件中施加的压力。
您可以将此与您的自定义视图实现结合起来,使用每个字母数字字符作为UIButtons接收触摸,并将其传递给您。
更新:
在与UIWindow讨价还价之后,我终于能够在苹果的标准键盘窗口中捕捉触摸事件。
诀窍是在UIWindow扩展中覆盖UIWindow(也可以在UIView级别上完成,但它将具有更广泛的含义,因为UIView是UIWindow的祖先),并且每当您看到来自UIRemoteKeyboardWindow的触摸时,就返回触摸处理对象。
extension UIWindow
{
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
print("kb touch")
for touch in touches
{
let pressure = touch.force
print("pressure is: \(String(describing: pressure))")
}
}
override open func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
print("hittest")
let view = super.hitTest(point, with: event)
if (NSStringFromClass(type(of: self)) == "UIRemoteKeyboardWindow")
{
//will result in touchesBegan being called
return self;
}
return view
}
}https://stackoverflow.com/questions/51726313
复制相似问题