Супер повільне відставання / затримка на початковій анімації клавіатури 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.