17

I've recently discovered a problem in my app that only seems to occur in iOS 10 where the system keyboard does not display when programmatically triggering a text field to become first responder inside of a completion handler -- specifically the completion handler I get back from a Touch ID attempt.

The crazy part of this issue is, even though the keyboard is not shown, the area on the iPhone where the keyboard normally would be is still responding to touch inputs as if the user is typing on the keyboard!

After doing a lot of investigation and debugging into the issue, I stumbled across the fact that the hidden property is set to YES on the private UIRemoteKeyboardWindow that gets created after becomeFirstResponder is invoked on the text field. In other situations where I bring up the keyboard, the value of that hidden property is set to NO.

Has anybody else run into this problem in iOS 10? If so, anybody found a solution to this? I tried manually setting the hidden value to YES on the window instance but that had no effect on it. I'm pretty much grasping at straws at this point.

Attachments:
Here's the output of the windows from the UIApplication instance when the text field becomes first responder outside of the Touch ID completion handler (pay close attention to UIRemoteKeyboardWindow):

becomeFirstResponder outside of Touch ID completion

And when the UITextField becomes the first responder inside the Touch ID handler...

becomeFirstResponder inside of Touch ID completion

First Update

So I did not consider the becomeFirstResponder being done on the main thread before that some have pointed out, but unfortunately, it did not resolve the issue -- however, I did make some additional discoveries. The hidden window issue seems to stem from outputting the details of the UIApplication instance's windows immediately after issuing the becomeFirstResponder action. After doing that, I set a breakpoint on the UITextField editing callback and proceed to interact with the keyboard (that is invisible) -- and when I output the window details, it doesn't seem like the hidden property is ever set to YES (which can possibly rule out that property being set as the cause of the issue), but I still have an invisible keyboard! I started debugging the view hierarchy and below is a screenshot of what it looks like when I examine the keyboard window:

Debugging Keyboard Window #1

Debugging Keyboard Window #2

Hopefully you guys can see what I discovered here which is that the keys are present but there appears to be some white view blocking them from sight. The thing is, I don't even see those white views on my app screen. I just see what normally sits behind the keyboard when it's present.

Danchez
  • 1,266
  • 2
  • 13
  • 28
  • Is the completion handler and your call to `becomeFirstResponder` being done on the main thread? – dan Aug 19 '16 at 18:50
  • Daniel, have you managed to overcome this? – theiOSDude Aug 22 '16 at 12:16
  • @theiOSDude, @dan --- sorry gents, was off for the weekend and didn't revisit this. Great thoughts on the main thread, totally forgot to consider that. Unfortunately, doing the `becomeFirstResponder` on the main queue did not resolve the issue of the hidden window. But I did make some other discoveries which I'll update the main post with. – Danchez Aug 22 '16 at 12:52
  • @DanielSanchez exactly the same thing that I am seeing. – theiOSDude Aug 22 '16 at 13:11
  • I've seen this issue happen on 2 different projects at work. Always the same setup: Calling `becomeFirstResponder` in a TouchID callback. Applying a delay (accepted answer) seems to be the only option so far. – Jean-Étienne Sep 26 '16 at 04:23

2 Answers2

16

As a temporary workaround, call becomeFirstResponder after a delay fixed this, however, not happy with the hacky solution.

theiOSDude
  • 1,480
  • 2
  • 21
  • 36
  • Wow, good find on that solution -- and definitely agreed on the unhappiness that we have to go as far hacking to get the desired result. How long of a delay did you have to set for the keyboard to appear? – Danchez Aug 22 '16 at 15:18
  • @DanielSanchez sweet, can you mark this answer as correct :) Applied a 1 second horrible delay and are revisiting after GM is released incase the issue is Beta related. – theiOSDude Aug 23 '16 at 10:13
  • really appreciate your time on this. You may have touched on it lightly already, but any thoughts/ideas on why we need to go this far and add a delay like this? I'm scratching my head trying to figure out why this is necessary and why the behavior is different on iOS 10 vs. iOS 9 -- (then again iOS 10 is still in beta so it may simply be that anything can happen while it's under development I suppose). – Danchez Aug 23 '16 at 18:13
  • @Danchez No problem, Im going to re-visit the issue was soon as GM is here as, like you said, we maybe trying to fix something incorrect in the UIKit for iOS10. :) Ill be sure to come back with my findings :) – theiOSDude Aug 26 '16 at 10:13
  • 3
    Can still occur on iOS 10.0.1 (release) – Ashton-W Sep 15 '16 at 07:52
  • Confirmed, shall I fire a radar off and see what the response is? – theiOSDude Sep 16 '16 at 15:09
  • 2
    I had the same issue and applied this workaround. Good news is that 0.1 second of delay works - much better than 1 second – Vincent Gigandet Sep 24 '16 at 10:00
  • 5
    I just filed rdar://28469072 with a sample project for easy reproduction, feel free to file duplicates ;) – Jean-Étienne Sep 26 '16 at 05:35
  • 1
    Thank you! After debugging several hours and found this answer very helpful. – Dinesh Raja Dec 07 '16 at 19:15
3

Looks like the issue occurring for different scenarios too - keyboard could be invisible even if you are selecting the textField manually after cancelling touchId alert.

leshque
  • 61
  • 3