5

I'm creating an native touch id alert with code:

    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)
        }
    })]

button handler that calls the native Touch ID alert looks like this:

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

    view.endEditing(true)
}

and this is the code of handleTouchIdAuthentication:

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

The problem is, that most of the time, when I cancel the Touch ID native dialog, the alert dismiss correctly and becomeFirstResponder() works OK.

However at around 1 in 10 times, becomeFirstResponder() returns true, passcodeDigitTextField1 gets focus, but the keyboard does not appear. Moreover keyboard will not show itself even if I change the focus to other text field by tapping them.

Strangly, this works fine for ios 9 and 8. The issue happens only on iOS 10.

Dzior
  • 1,485
  • 1
  • 14
  • 30

4 Answers4

2

As Rajan mentioned:

Just a hack. Can you just do passcodeDigitTextField1.becomeFirstResponder() in a function and call that function with a delay of 0.25 or 0.5 seconds using performSelector and tell the result –

This worked, I ended up with 0.01 delay

I will not mark this answer as this is only a workaround.

Dzior
  • 1,485
  • 1
  • 14
  • 30
  • 1
    I also faced same issue in iOS 10.2 . Using this workaround somehow fixed my problem. – Rahul Dec 16 '16 at 10:17
2

This was happening to me every time in exactly the same situation, trying to set field focus after a failed Touch ID authentication. I solved it by subscribing to UIApplicationDidBecomeActiveNotification on the default NSNotificationCenter and putting my call to becomeFirstResponder inside that.

ApplicationDidBecomeActive fires slightly after the Touch ID callback, which might explain the problem.

It's slightly more awkward to code for but it's working 100% of the time so far. Way better than performSelector.

Tom K
  • 430
  • 5
  • 22
1

Can you try doing this. Not Sure it will work!

DispatchQueue.main.async {
      passcodeDigitTextField1.becomeFirstResponder()
}
Rajan Maheshwari
  • 14,465
  • 6
  • 64
  • 98
  • I did with classic GCD dispatch_async. It didn't help. We are using swift2 ATM – Dzior Oct 28 '16 at 14:43
  • 1
    Just a hack. Can you just do `passcodeDigitTextField1.becomeFirstResponder()` in a function and call that function with a delay of 0.25 or 0.5 seconds using performSelector and tell the result – Rajan Maheshwari Oct 28 '16 at 14:48
  • 0.25 Seems to did a good work, as I was not able to reproduce this issue with this. Will try to fine-tune this number at Wednesday as, the holidays came. There is one more problem with this. On iOS 10 in contrary to 9 and 8 this becomeFirstResponder even without the 0.25 delay apply focus on the control after around 1 second which is a noticeably crappy user experience, additional 0.25 second does not make it better :/ – Dzior Oct 28 '16 at 15:12
  • @Dzior We can have OS version checks here. Don't do delay in 9 and 8 – Rajan Maheshwari Oct 28 '16 at 15:14
  • 1
    Still, this is only a really bad hack, and user experience for 10 is bad ATM – Dzior Nov 02 '16 at 08:07
0

It might sound really stupid but... in my case once it helped to restart the whole device. Just that. It was also iOS 10 only. ;) Maybe there is someone with a similar problem out there and did not try that before checking stack overflow since it seems kind of weird to just restart the device for an error like this.

Colibri
  • 713
  • 12
  • 16