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


169

Гаразд, ця проблема зводила мене з глузду.

Після того, як я торкнуться своєї, клавіатура з’явиться приблизно 3-4 секунди UITextField. Це відбувається лише при першому появі клавіатури з моменту запуску програми, після чого анімація запускається миттєво.

Спочатку я думав, що це проблема завантаження занадто великої кількості зображень чи моїх UITableView, але я просто створив абсолютно новий проект із лише a 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 секунди після того, як перегляд завантажується, перш ніж торкнутися текстового поля, я не отримаю затримки.

Відповіді:


291

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


2
Це було правильною відповіддю в моєму випадку на iPhone 5 під управлінням iOS 8.1 - у мене виникло затримка на 1 секунду для першої клавіатури.
— bejonbee

7
Так, відставання відбувається лише при налагодженні. Дивно.
— Полс

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, наведена нижче
— америк

4
З цим слід було б
— вчинити

9
Дякую! Проблема все ще залишається на ios8, на жаль, але ця
— обробка

1
@Vadoff Solution працює, але у мене є 2 мінуси: 1) у мене близько 1 додаткової секунди завантаження програми; 2) Отримано попередження про пам’ять (але, не весь час). Я спробував додати цей код до UIViewController у viewDidLoad, але це не мало ефекту, можливо, я зробив щось не так? Чи можете ви відредагувати свою відповідь і додати код для контролера перегляду, якщо це можливо.
— Діма Деплов

16
Те, що це правильна відповідь і працює, змушує мене плакати. Мені довелося прийняти душ після застосування цього зламу.
— Білл Берджесс

27

Так, я також отримав кілька секунд затримки на останньому iPhone 4s. Не панікуйте. З деяких причин це відбувається лише в перший раз, коли додаток завантажується з Xcode у налагодженні. Коли я випустив, я не отримую затримки. Просто забудь це...


6
Це пов'язано з рівнем оптимізації: Fastest, Smallest [-Os]. Ви можете змінити йогоBuild Settings > Optimization Level
— Карлос Рікардо

20

3
Дякую, багато посилань згадують про затримку, яка становить приблизно "1 секунду на старих iphone", "не така помітна на 3g" та "миттєво завантажується на нових пристроях", але я відчуваю набагато більшу затримку на 3-4 секунди на iphone 4s. Спробую передзавантажити клавіатуру далі, але я переживаю, що щось інше може бути проблемою (можливо, ios5 чи мій xcode ver?).
— Vadoff

Ви спробували, як UITextField та клавіатура поводяться у нативній програмі? Обов'язково вийміть його з пам'яті для цього тесту (двічі клацніть на домашній кнопці ...). Немає нічого поганого в опублікованому вами коді, і за 3-4 секунди насправді здається багато - занадто багато. Я ніколи не пробував цю попередню завантаження, але це схоже на єдине вирішення.
— Рок Ярк

Так, текстове поле пошуку для Карт відображає клавіатуру миттєво при натисканні після запуску. Я вийняв його з пам’яті і кілька разів спробував, щоразу миттєво. Я не впевнений, що сталося, чому моє так повільно.
— Вадофф

Щойно робив тест на одному з моїх додатків, які використовують UITextField - відставання дійсно має бути мінімальним. Код, який ви опублікували, здається прекрасним, тому має бути ще щось, що стримує основну нитку. Це може бути вдалий час для запуску сумнозвісних інструментів.
— Rok Jarc

23
Гаразд, для всіх, хто, схоже, має цю проблему. Я виявив, що це сталося лише в перший раз, коли додаток було оновлено на iphone від xcode. Після завантаження програми на iphone будь-яке подальше використання програми призведе до нормальної поведінки (я кілька разів вилучив програму з пам'яті / перезапустив iphone, щоб переконатися).
— Вадофф

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 postalaFirstResponder]; дуже складно для головної нитки?
— Сергій Петрук

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

@Kevin, але щось блокує основний потік, і в результаті анімація на клавіатурі не працює. Я згоден з вами, але, на мою думку, рішення з текстом, поданим у програміDelegate, погано пахне.
— Сергій Петрук


1

Пов'язану проблему, коли UIViewController буде повільно представляти, було вирішено за допомогою системного шрифту замість спеціального шрифту на полі UITextField. Можливо, використання шрифту системи може також працювати для цієї проблеми?


0

Здається, ця помилка виправлена ​​в iOS 9.2.1. З моменту оновлення свого пристрою у мене більше не виникає затримок між натисканням на текстове поле та клавіатурою, які з’являються під час підключення мого пристрою до мого комп'ютера.


1
Здається, це виправлено на iPhone, але у мене все ще є відставання на iPad.
— Adarkas2302

0

Ця вибрана відповідь спричиняє збій BAD_EXC на iOS 11 - видаліть з програми, щоб виправити


-2

Ви можете додати код нижче, коли вигляд viewController завантажився, як viewDidAppear.Не лише додаток: 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.