Подтвердить что ты не робот

IPhone. Слайд-панель с клавиатуры открывается справа, как при редактировании заметки в приложении "Контакты".

Я ищу способ сдвинуть клавиатуру вправо справа, например, что происходит в приложении "Контакты" при редактировании заметки.

Моя проблема в том, что когда я вызываю [someTextView getFirstResponder] в viewWillAppear, клавиатура сразу же появляется без анимации. И когда я вызываю его в viewDidAppear, сначала открывается слайд справа (UINavigationController выполняет разворот), а затем клавиатура соскальзывает снизу.

Возможно ли, чтобы клавиатура сместилась справа, вместе с представлением?

4b9b3361

Ответ 1

Все, что вам нужно сделать, это сообщить рассматриваемому текстовому представлению, чтобы он стал первым ответчиком в методе viewDidLoad контроллера вида, который вы нажимаете на стек навигации:

override func viewDidLoad() {
    super.viewDidLoad()
    someTextView.becomeFirstResponder()
}

Это работает в iOS 8. Клавиатура скользит справа и вместе с представлением.

Ответ 2

Решение

В iOS 7 работает вызов becomeFirstResponder on _textView в viewDidLayoutSubviews.

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [_textView becomeFirstResponder];
}

Примечание. Выполнение этого в viewWillLayoutSubviews также работает.

Описание

Прочитайте обсуждение в документах для becomeFirstResponder.

Вы можете вызвать этот метод, чтобы создать объект-ответчик, такой как вид первого ответчика. Однако вы должны вызывать его только на этом представлении, если оно является частью иерархии представлений. Если свойство views window содержит объект UIWindow, он был установлен в иерархии представлений; если он возвращает nil, представление отделяется от любой иерархии.

При использовании навигационного контроллера для выведения вашего пользовательского контроллера просмотра на экран self.view.window по-прежнему nil к моменту вызова viewDidLoad или viewWillAppear:. Таким образом, _textView.window также nil в тех же методах, поскольку _textView является подзоном self.view, т.е. Они оба находятся в одном окне. Независимо от того, как вы представляете свой настраиваемый контроллер представлений, self.view.window (и, следовательно, _textView.window) также nil в initWithNibName:bundle:. self.view.window устанавливается к тому времени, когда вызывается viewDidAppear:, но это слишком поздно, потому что к тому времени контроллер навигации уже завершил анимацию нажатия на экране на экране.

self.view.window также устанавливается к тому времени, когда вызывается либо viewWillLayoutSubviews, либо viewDidLayoutSubviews, и эти методы вызывают до начала анимации push навигационного контроллера. Итак, почему он работает, когда вы делаете это в любом из этих методов.

К сожалению, viewWillLayoutSubviews и viewDidLayoutSubviews получают гораздо больше, чем только на начальном навигационном контроллере. Но, navigationController:willShowViewController: и willMoveToParentViewController: вызывается слишком рано (после viewDidLoad, но до того, как будет установлен self.view.window), а navigationController:didShowViewController: и didMoveToParentViewController: получат слишком поздно (после анимации push).

Единственный способ, которым я могу это сделать, - это каким-то образом наблюдать свойство window _textView, чтобы вы получили уведомление, когда оно изменилось, но я не уверен, как это сделать, поскольку window readonly.

Ответ 3

В iOS 7 (или любой версии до) вы можете сделать простую вещь в loadView, viewDidLoad или viewWillAppear

[yourTextView performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.0];

В этом случае вы получите слева направо появление клавиатуры, выровненной с движением нажатия кнопки просмотра.

Ответ 4

Для iOS 7 я нашел следующее решение для работы наилучшим образом для меня:

-Import UIResponder-KeyboardCache в ваш проект.

-Add [UIResponder cacheKeyboard:YES]; до viewDidLoad представления перед представлением клавиатуры. Лучше сделать это сразу, когда приложение загрузится или в удобное для вас время, когда вы можете себе это позволить (например, при HTTP-запросе). В большинстве случаев просто в представлении до этого достаточно.

- добавьте следующее к viewDidLoad в виде клавиатуры.

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

Чтобы объяснить, это предварительно загрузит представление клавиатуры, которое позволит удалить задержку с первого вызова вида клавиатуры. Вызов becomeFirstResponder в текстовом поле в главной очереди заставляет его перемещаться с представлением вместо того, чтобы анимировать вверх до того, как будет отображаться представление.

Ответ 5

Вы можете попытаться отправить сообщение getFirstResponder новому контроллеру представления, прежде чем вставлять его в стек. Например:

-(void)functionWhereYouPushTheNewViewController {
  yourNewViewController *newVC = [[yourNewViewController alloc] init];
  [newVC.yourTextView becomeFirstResponder];
  [self.navigationController pushViewController:newVC animated:YES];
}

Я обнаружил, что изменение анимации на таких вещах, как клавиатура, довольно сложно, и если вы читаете "Руководства по человеческому интерфейсу", Apple делает совершенно ясным, что они хотят, чтобы определенные вещи действовали определенным образом, все время. Есть способы изменить поведение определенных анимаций, но они часто включают недокументированные вызовы API и являются основанием для отказа от магазина приложений. Это было бы нарушение HIG, если бы нажали на слайд-шоу снизу, например.

Надеюсь, что это поможет.