【问题标题】:becomeFirstResponder sometimes does not open the keyboard on ios 10becomeFirstResponder 有时无法在 ios 10 上打开键盘
【发布时间】:2016-10-28 14:36:21
【问题描述】:

我正在使用代码创建本机触摸 ID 警报:

    let context = LAContext()

    guard deviceCanUseTouchId(context: context) else {
        return
    }

    presentingAlert = true
    [context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "touch_id_auth_message".localized(), reply: { [unowned self] success, error -> Void in
        self.presentingAlert = false
        self.canPresentAlert = true

        dispatch_async(dispatch_get_main_queue()) {    
            completionHandler?(success)
        }
    })]

调用本机 Touch ID 警报的按钮处理程序如下所示:

@IBAction func touchUpInsideUseTouchIdButton(sender: AnyObject) {
    ACTouchId.sharedManager.authenticateWithTouchId(completionHandler: { [weak self] in
        self?.handleTouchIdAuthentication(granted: $0)
        })

    view.endEditing(true)
}

这是handleTouchIdAuthentication的代码:

private func handleTouchIdAuthentication(granted granted: Bool) {
    if granted {
        //...
    } else {
        passcodeDigitTextField1.becomeFirstResponder()
    }
}

问题是,在大多数情况下,当我取消 Touch ID 原生对话框时,警报会正确关闭并且 becomeFirstResponder() 工作正常。

然而,在大约 10 次中,becomeFirstResponder() 返回 true,passcodeDigitTextField1 获得焦点,但键盘没有出现。此外,即使我通过点击它们将焦点更改为其他文本字段,键盘也不会显示自己。

奇怪的是,这适用于 ios 9 和 8。此问题仅在 iOS 10 上发生

【问题讨论】:

  • 你能在主线程中做那部分吗?
  • 你是用模拟器还是真机?
  • 我正在使用带有 iOS 10.0.2 的实际设备。
  • handleTouchIdAuthentication 方法实际上被分派到主队列(参见完成处理程序代码在第一个 sn-p 中分派)

标签: ios swift ios10 touch-id becomefirstresponder


【解决方案1】:

正如拉詹所说:

只是一个技巧。你能做到吗 passcodeDigitTextField1.becomeFirstResponder() 在函数中调用 该功能使用延迟 0.25 或 0.5 秒 performSelector 并告诉结果——

这行得通,我得到了 0.01 的延迟

我不会标记此答案,因为这只是一种解决方法。

【讨论】:

  • 我在 iOS 10.2 中也遇到了同样的问题。使用这种解决方法以某种方式解决了我的问题。
【解决方案2】:

每次都在完全相同的情况下发生这种情况,尝试在 Touch ID 身份验证失败后设置字段焦点。我通过在默认的 NSNotificationCenter 上订阅 UIApplicationDidBecomeActiveNotification 并将我的电话放在其中的 becomeFirstResponder 来解决它。

ApplicationDidBecomeActive 在Touch ID 回调之后稍微触发,这可能解释了问题。

编写代码稍微有点尴尬,但到目前为止它 100% 的时间都在工作。比 performSelector 好得多。

【讨论】:

    【解决方案3】:

    你能试试这个吗?不确定它会起作用!

    DispatchQueue.main.async {
          passcodeDigitTextField1.becomeFirstResponder()
    }
    

    【讨论】:

    • 我使用了经典的 GCD dispatch_async。它没有帮助。我们正在使用 swift2 ATM
    • 只是一个小技巧。你可以在一个函数中执行passcodeDigitTextField1.becomeFirstResponder() 并使用 performSelector 以 0.25 或 0.5 秒的延迟调用该函数并告诉结果
    • 0.25 似乎做得很好,因为我无法用这个重现这个问题。将在星期三尝试微调这个数字,因为假期来了。这还有一个问题。在 iOS 10 上,与 9 和 8 不同,即使没有 0.25 的延迟,这 becomeFirstResponder 也会在大约 1 秒后将焦点应用到控件上,这是一个明显糟糕的用户体验,额外的 0.25 秒并不能让它变得更好:/
    • @Dzior 我们可以在这里进行操作系统版本检查。不要在 9 点和 8 点做延迟
    • 不过,这只是一个非常糟糕的 hack,10 的用户体验是糟糕的 ATM
    【解决方案4】:

    这听起来可能很愚蠢,但是……就我而言,一旦它有助于重新启动整个设备。只是。它也仅限于 iOS 10。 ;) 也许有人有类似的问题,并且在检查堆栈溢出之前没有尝试过,因为对于这样的错误重启设备似乎有点奇怪。

    【讨论】:

      猜你喜欢
      • 2022-12-01
      • 1970-01-01
      • 2021-06-27
      • 2018-05-27
      • 1970-01-01
      • 2012-04-02
      • 2021-05-05
      • 2020-04-21
      • 1970-01-01
      相关资源
      最近更新 更多