39

The Problem

In most iPhone apps, there's a quite a bit of delay the first time that the keyboard is presented (presumably creating the keyboard takes quite a bit of oomph, even on an iPhone 4).

Most people seem ok with this. I'm not, it really bugs me - and the way my app is presented, users will be very confused that nothing happens for a few seconds when they tap on a text field for the first time.


What I've Tried

Googling it brings up one solution - unfortunately this is invalid as of iOS 4 (see here).

I don't expect the solution to be easy to find, if I could put a bounty on this straight away I would. I would be very stoked if someone figured out a solution. All the solution needs to do is load the keyboard without the user being aware.


So..

Any ideas are appreciated. Complete, working code (for iOS 4 and 5) is bounty worthy (even if the bounty has to come later!).

If a solution is found I plan to create a self contained 'KeyboardPreloader' class that people can drop into their project, and preload the keyboard with one line of code :)

colincameron
  • 2,696
  • 4
  • 23
  • 46
Jordan Smith
  • 10,310
  • 7
  • 68
  • 114
  • I can't say I've really noticed any delay. Is this delay present in all the apps on the phone or only the app that you are developing? If it is the same delay as in all the other apps then there probably isn't anything you can do about it. If it is only in your app then please show us the pertinent code. – sosborn Feb 02 '12 at 06:52
  • @sosborn [textField becomeFirstResponder]. I've noticed it in some other apps, and whoever wrote the blog linked above noticed it too. Perhaps there are only some circumstances that it occurs in - if this is the case then knowing what these circumstances are would be the answer. – Jordan Smith Feb 02 '12 at 06:57
  • Well, is your app doing anything else while while loading the keyboard? Any UI elements being updated? There are so many things that could affect this, even things not related to your app (background processes, etc.) – sosborn Feb 02 '12 at 06:59
  • @sosborn no, presenting the keyboard is the only thing it does. If I get time I'll create a mini project that has the problem in it :) – Jordan Smith Feb 02 '12 at 07:06
  • I have noticed this kind of problem on iPad first generation, not the second. Strange but probably logical - iPad 2 has much better cpu. I don't think there is to much to do about this... – Borut Tomazin Feb 02 '12 at 07:53
  • 1
    What about making the textfield the firstResponder and then resigning it in the viewdidload.. this seems to work with no lag when the keyboard is loaded again... – Ankit Srivastava Feb 02 '12 at 07:54
  • @AnkitSrivastava Ahh so potentially it would work to load it on a view that never gets presented. Thanks, I'll play around with that and see if I have any luck. – Jordan Smith Feb 02 '12 at 08:06
  • Yup.. (Shit I missed the Bounty.. :P) I should have posted this as an answer. – Ankit Srivastava Feb 02 '12 at 08:24
  • @AnkitSrivastava haha. Hmmm doesn't seem to be working though anyway, it's like the keyboard has to be 'visible' for it to actually load. I'll keep playing around with it though. – Jordan Smith Feb 02 '12 at 08:26
  • I'm unable to replicate this issue on device/simulator x(. The delay for me is hardly half a second! – tipycalFlow Feb 02 '12 at 10:00
  • @tipycalFlow hmm what device? The delay is about a second for me on iPhone 4. I'm guessing this is pretty much zero for iPhone 4S as is the simulator. Also, you need to quit whatever app it is you're testing it on and start over, it only happens the first time you load the keyboard in that app. – Jordan Smith Feb 02 '12 at 10:31
  • @AnkitSrivastava as in the solution, or did you not have the problem in the first place? If your solution is working, would you mind posting the code that you used :) – Jordan Smith Feb 02 '12 at 10:32
  • the lag on my device is about half a second.. so when I do the above mentioned thing in my viewDidLoad the problem goes away. – Ankit Srivastava Feb 02 '12 at 10:40
  • @AnkitSrivastava ok thanks, I'll have another go tomorrow. This sounds weird, but now the whole loading/latency issue doesn't occur at all... definitely not like it was before!! Maybe iOS decided to start keeping it in memory or something silly. I think I need sleep, I'm probably seeing things. Or maybe I should test on an older device where the problem is accentuated quite a bit (heaps of apps used to do it for me on my old 3G). Anyway, write your solution as an actual answer - if it's working for you I should be able to get it to work tomorrow and give you a bounty ;) – Jordan Smith Feb 02 '12 at 10:57
  • @Jordan I wouldn't say it happens only the first time...I think it's quite random - probably depends on the current CPU load or something...XO – tipycalFlow Feb 02 '12 at 20:04

4 Answers4

30

UIResponder+KeyboardCache was written to address this exact problem.

From that project's readme:

This category on UIResponder gives you a simple method +cacheKeyboard so that you can control when this caching work is done. For example, if you are loading some data from a server, then you could invoke this during that downtime. There is another method +cacheKeyboard: that takes an optional BOOL value. Passing YES to this method causes the cache invocation to happen on the next runloop. So, if you performed an animation just before calling this method it would not interrupt that animation.

cbowns
  • 6,295
  • 5
  • 47
  • 64
12

making the textfield the firstResponder and then resigning it in the viewdidload.. this seems to work with no lag when the keyboard is loaded again...

- (void)viewDidLoad
{
    [super viewDidLoad];

    [textField becomeFirstResponder];
    [textField resignFirstResponder];
        // Do any additional setup after loading the view, typically from a nib.
}
Ankit Srivastava
  • 12,347
  • 11
  • 63
  • 115
  • As far as I can tell, this seems to work. I didn't realize you meant just two lines of code, was trying something more complex before you posted this ;) It's a bit hard to test, because sometimes the latency doesn't show up on iPhone 4 at all, but after a day or so I haven't experienced lag using this code. Can't quite believe the answer is so simple! But will award a bounty in a few days anyway since I said I would, assuming no better answer is posted and it does still work after some more testing :) – Jordan Smith Feb 03 '12 at 21:24
  • To interested bounty hunters: THIS DOESN'T WORK FOR ME. IT DOESN'T DO ANYTHING. I AM INTERESTED IN DIFFERENT ANSWERS! – Claudiu Oct 23 '13 at 17:10
  • Like @Claudiu says, I no longer believe this answer works. Not sure whether this answer ever worked in the first place, or it's due to a change in iOS. – Jordan Smith Oct 26 '13 at 04:32
  • @Jordan Well I am not sure either now, but at the time when I gave this answer it used to work. And also I found that this was the case only when you had the app installed for the very first time in debugging mode, it didn't use to occur in the subsequent runs. – Ankit Srivastava Oct 26 '13 at 06:55
  • 1
    @Jordan Check out the .m files for [This Github Page](https://github.com/mbrandonw/UIResponder-KeyboardCache) Same general concept as above. I can 100% say that throwing this in the viewDidLoad of my intro container controller made my iPad app keyboard appearance later on Much faster. – Taylor Halliday Nov 01 '13 at 00:35
  • @TaylorHalliday: thanks for the comment! would not have noticed the new answer if not for that. brilliant. – Claudiu Nov 01 '13 at 18:38
  • `viewDidAppear` seems to be much more reliable way. – Brian Cannard Jan 11 '15 at 17:29
7

Here's what I do:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Preloads keyboard so there's no lag on initial keyboard appearance.
  UITextField *lagFreeField = [[UITextField alloc] init];
  [self.window addSubview:lagFreeField];
  [lagFreeField becomeFirstResponder];
  [lagFreeField resignFirstResponder];
  [lagFreeField removeFromSuperview];
}

Super slow lag/delay on initial keyboard animation of UITextField

Community
  • 1
  • 1
Vadoff
  • 9,219
  • 6
  • 43
  • 39
0

Once a user complain my app of the slow loading keyboard. Here is a little trick to disable the keyboard animation:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // ...

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(willShowKeyboard:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didShowKeyboard:)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];

    // ...
}


- (void)willShowKeyboard:(NSNotification *)notification
{
    [UIView setAnimationsEnabled:NO];
}

- (void)didShowKeyboard:(NSNotification *)notification
{
    [UIView setAnimationsEnabled:YES];
}

It may not answer the question directly, as the keyboard itself is in the main UI for my example and caching is not the option to me. Nevertheless, the overall responsiveness is improved.

ohho
  • 50,879
  • 75
  • 256
  • 383