Супер медленная задержка / задержка при начальной анимации клавиатуры UITextField


169

Хорошо, эта проблема сводит меня с ума.

Клавиатура всплывает после того, как я прикоснусь к ней UITextField. Это происходит только при первом появлении клавиатуры после запуска приложения, после чего анимация запускается мгновенно.

Сначала я подумал, что это проблема загрузки слишком большого количества изображений или моего UITableView, но я только что создал новый проект только с одним UITextField, и я все еще испытываю эту проблему. Я использую iOS 5, Xcode ver 4.2 и работаю на iPhone 4S.

Это мой код:

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 30)];
    textField.borderStyle = UITextBorderStyleRoundedRect;
    textField.delegate = self;
    [self.view addSubview:textField];
}

@end

Это общая проблема для всех приложений?

Прямо сейчас, единственный способ сделать это несколько лучше - textFieldстать / подать в отставку первым респондентом viewDidAppear, но это не решает проблему полностью - она ​​просто загружает задержку, когда вместо этого загружается представление. Если я щелкну textFieldсразу после загрузки представления, я все равно получу проблему; если я подожду 3-4 секунды после загрузки представления, прежде чем дотронуться до textField, я не получу задержку.

Ответы:


291

Прежде чем применять какие-либо экзотические хаки для решения этой проблемы, попробуйте следующее: остановите сеанс отладки, закройте приложение от многозадачности, отключите устройство от компьютера и запустите приложение, нажав на его значок. Я видел по крайней мере два случая, в которых задержка происходит, только когда устройство подключено.


2
Это был правильный ответ в моем случае на iPhone 5 под управлением iOS 8.1 - у меня была задержка около 1 секунды для первой клавиатуры.
bejonbee

7
Да, отставание происходит только при отладке. Weird.
Паулс

16
Спасибо. Эта проблема все еще присутствует в iOS 9.1 / Xcode 7.1, Swift 2.1.
Ярослав

4
FYVM Apple, FYVM. 90 минут времени в срок, который я не могу себе позволить. 20 голосов, если бы я мог. Все еще присутствует в iOS9.2 / Xcode 7.2
BaseZen

1
Это было именно то, что моя проблема была тоже. После того, как я отключил компьютер от Mac, задержки не было (ios9) xcode 7.2
Устаревший Даррен

148

Таким образом, проблема не ограничивается первой установкой, как я думал ранее, а возникает каждый раз, когда приложение запускается. Вот мое решение, которое решает проблему полностью.

- (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];
}

1
Хороший и простой @Vadoff - это встроенная версия примера UIResponder + KeyboardCache, приведенного ниже
amergin

4
Это должно было быть обработано ОС ... ну да ладно: /
chakrit

9
Спасибо! К сожалению, проблема все еще остается на ios8, но этот
обходной путь

1
@Vadoff Solution работает, но имеет 2 минуса: 1) у меня есть примерно 1 дополнительная секунда загрузки приложения; 2) Получено предупреждение о памяти (но не всегда). Я пытался добавить этот код в UIViewController в viewDidLoad, но безрезультатно, может я что-то не так сделал? Не могли бы вы отредактировать свой ответ и добавить код для просмотра контроллера, если это возможно.
Дима Деплов

16
Тот факт, что это правильный ответ и работает, заставляет меня плакать. Я должен был принять душ после применения этого хака.
Билл Берджесс

27

Да, я также получил несколько секунд задержки на последнем iPhone 4s. Не паникуйте. По некоторым причинам это происходит только при первой загрузке приложения из Xcode в Debug. Когда я сделал релиз, я не получил задержку. Просто забудь это...


6
Это связано с уровнем оптимизации Fastest, Smallest [-Os]. Вы можете изменить это наBuild Settings > Optimization Level
Карлос Рикардо

20

3
Спасибо, во многих ссылках упоминается, что задержка составляет около «1 секунды на старых iPhone», «не так заметно на 3g» и «мгновенно загружается на новых устройствах», но я испытываю гораздо более длительную задержку 3-4 секунд на iphone 4s. Затем я попытаюсь предварительно загрузить клавиатуру, но я боюсь, что что-то еще может быть проблемой (возможно, ios5 или моя версия xcode?).
Vadoff

Вы пробовали, как UITextField и клавиатура ведут себя в нативном приложении? Обязательно удалите его из памяти перед этим тестом (дважды нажмите кнопку «Домой» ...). Нет ничего плохого в том фрагменте кода, который вы разместили, и 3-4 секунды действительно кажутся много - слишком много. Я никогда не пробовал эту предварительную загрузку, но похоже, что это единственный обходной путь.
Рок Джарк

Да, функция поиска textField for Maps мгновенно вызывает клавиатуру при нажатии после запуска. Я удалил это из памяти и попробовал несколько раз, это каждый раз мгновенно. Я не уверен, что случилось, почему мой так медленно.
Vadoff

Только что сделал тест на одном из моих приложений, которые используют UITextField - задержка должна быть минимальной. Код, который вы разместили, выглядит хорошо, поэтому должно быть что-то еще, сдерживающее основной поток. Это может быть хорошее время для запуска печально известных инструментов.
Рок Джарк

23
Хорошо, для всех, у кого, похоже, есть эта проблема. Я обнаружил, что это произошло только в первый раз, когда приложение было обновлено на iphone из xcode. После загрузки приложения на iphone любое дальнейшее использование с приложением приведет к нормальному поведению (я несколько раз удалял программу из памяти / перезагружал свой iphone, чтобы убедиться).
Vadoff

18

Вы можете использовать решение Vadoff в Swift, добавив его в didFinishLaunchingWithOptions:

// Preloads keyboard so there's no lag on initial keyboard appearance.
let lagFreeField: UITextField = UITextField()
self.window?.addSubview(lagFreeField)
lagFreeField.becomeFirstResponder()
lagFreeField.resignFirstResponder()
lagFreeField.removeFromSuperview()

Это работает для меня в iOS 8.


5

Код в блоке добавляется в основную очередь и выполняется асинхронно. (не заблокирован основной поток)

dispatch_async(dispatch_get_main_queue(), ^(void){
      [textField becomeFirstResponder];
 });

6
Попробуйте добавить текстовое объяснение, которое описывает, почему ваш код работает, а не просто дать его, чтобы другие могли извлечь из него урок.
Сани

7
Этот код фактически блокирует основной поток, который вы отправляете в главную очередь ...
Werner Altewischer

Вы знаете разницу между dispatch_async / dispatch_sync? И как вы думаете [textField становитьсяFirstResponder]; очень сложно для основного потока?
Сергей Петрук

@Spetruk Поток, вызывающий dispatch_async, не заблокирован, но поток, на котором вы фактически выполняете код, определенно заблокирован. Один поток не может делать две вещи одновременно, поэтому этот код блокирует основной поток (из-за dispatch_get_main_queue), но не блокирует поток, в котором вызывается dispatch_async.
Кевин

@Kevin, но что-то блокирует основной поток, и в результате клавиатурная анимация не работает. Я согласен с вами, но мое мнение, решение с textFiled в appDelegate пахнет плохо.
Сергей Петрук


1

Связанная проблема, когда UIViewController будет отображаться медленно, была решена путем использования системного шрифта вместо пользовательского шрифта в UITextField. Возможно, использование системного шрифта также подойдет для этой проблемы?


0

Эта ошибка, кажется, исправлена ​​в iOS 9.2.1. После обновления моего устройства у меня больше не возникает задержка между нажатием текстового поля и появлением клавиатуры, когда мое устройство подключено к моему компьютеру.


1
Кажется, это исправлено на iPhone, но у меня все еще есть отставание на iPad.
Adarkas2302

0

Этот выбранный ответ вызывает сбой BAD_EXC на iOS 11 - удалить из приложения, чтобы исправить


-2

Вы можете добавить приведенный ниже код, когда представление viewController действительно загрузилось, например viewDidAppear. Не просто application: didFinishLaunchingWithOptions:

UITextField *lagFreeField = [[UITextField alloc] init];
[self.window addSubview:lagFreeField];
[lagFreeField becomeFirstResponder];
[lagFreeField resignFirstResponder];
[lagFreeField removeFromSuperview];
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.