首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在iOS系统键盘上测量触摸压力(击键)?

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

Stack Overflow用户
提问于 2018-08-07 12:01:57
回答 2查看 1.1K关注 0票数 3

使用自定义UIGestureRecognizer可能无法测量触摸压力,因为我们不能直接访问系统键盘的视图1。如果使用自定义inputViewController,它可以实现,但对我来说不是选项。我想存储键保持时间和每个键的按键压力。你知道怎么做吗?

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

我认为,对Nirav的回答进行改进可以解决这个问题,但它禁用了键盘视图上的触摸功能。当我触摸一个键时,它输出触摸的力量,但是相应的字母没有被输入到文本字段。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-21 09:08:05

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

首先,创建一个自定义UIGestureRecognizer来侦听击键。这个步骤的实现被跳过了,因为它很简单(只覆盖touchesBegantouchesMovedtouchesEnded)。

添加KeyboardManager以访问键盘视图:

代码语言:javascript
复制
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扩展函数:

代码语言:javascript
复制
@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没事。不能向视图中添加具有相同类型的多个抽头手势识别器。

票数 1
EN

Stack Overflow用户

发布于 2018-08-08 08:03:26

从iOS 9开始,作为3D触摸的一部分,UITouch有力性质给你提供了在触摸事件中施加的压力。

您可以将此与您的自定义视图实现结合起来,使用每个字母数字字符作为UIButtons接收触摸,并将其传递给您。

更新:

在与UIWindow讨价还价之后,我终于能够在苹果的标准键盘窗口中捕捉触摸事件。

诀窍是在UIWindow扩展中覆盖UIWindow(也可以在UIView级别上完成,但它将具有更广泛的含义,因为UIViewUIWindow的祖先),并且每当您看到来自UIRemoteKeyboardWindow的触摸时,就返回触摸处理对象。

代码语言:javascript
复制
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
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51726313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档