InputAccessoryView состыковался внизу

Я пытаюсь добиться аналогичного поведения позиционирования, как панель ввода нижнего текста в приложении «Сообщения Apple».

Я пробовал много подходов, искал высоко и низко, и есть много подобных вопросов, но ни один из них не был удовлетворительным.

Указать:

  1. В нижней части UIToolbar есть UIToolbar
  2. Панель инструментов должна следовать за клавиатурой, когда клавиатура появляется и исчезает
  3. Панель инструментов должна оставаться на клавиатуре, когда клавиатура видна
  4. Когда клавиатура скрыта, панель инструментов остается («состыкована») в нижней части окна просмотра

Предлагаемые решения:

Ручная анимация панели инструментов в ответ на уведомления о появлении клавиатуры

Это решение не соответствует специальному случаю второго требования ( панель инструментов должна следовать за клавиатурой, когда клавиатура появляется и исчезает ):

  • В iOS 7 был введен UIScrollViewKeyboardDismissMode . Это позволяет интерактивный жест для отклонения клавиатуры. Когда пользователь катится мимо верхнего края клавиатуры, постепенно меняется рамка клавиатуры. Это решение ничего не делает для размещения этого поведения и просто оставляет панель инструментов в анимированной позиции.

Кроме того, это решение также не выполняет специальный случай третьего требования ( панель инструментов должна оставаться на клавиатуре, когда клавиатура видна ):

  • Вращение. Это решение требует дополнительного, досадно постороннего кода (как мы увидим в следующем предлагаемом решении) для поворота панели инструментов в ответ на вращение устройства.

Еще одна проблема с этим решением:

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

Следующее предлагаемое решение:

Использовать UIResponder inputAccessoryView

Это решение похоже на то, как Apple намерена поддерживать такое поведение, поскольку оно устраняет все недостатки ручного анимирования панели инструментов. Но это решение полностью пропускает четвертое требование ( когда клавиатура скрыта, панель инструментов остается («состыкована») в нижней части представления ).


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

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

5 Solutions collect form web for “InputAccessoryView состыковался внизу”

Я просто показал «решение» Джейсона Формана (@threeve). На вашем контроллере просмотра (да, контроллер просмотра) добавьте inputAccessoryView: и верните представление, которое хотите состыковать внизу, и переместите его с клавиатуры. Это просто работает. На самом деле представление не должно быть в вашей иерархии просмотров, оно будет автоматически вставлено контроллером представления.

edit: также реализует canBecomeFirstResponder и возвращает ДА ​​(как отметил Макс Силеманн). reloadInputViews также может быть полезен.

Вышеупомянутое решение Джонатана Бадена работало для меня. Вот код от Arik, показывающий, как его реализовать (это должно идти в вашем соответствующем контроллере представления):

  - (BOOL)canBecomeFirstResponder{ return YES; } - (UIView *)inputAccessoryView{ return self.inputAccessoryToolbar; // where inputAccessoryToolbar is your keyboard accessory view } 

Для тех, кто ищет версию Swift:

Подключите панель инструментов (в моем случае « myToolBar ») к контроллеру вашего представления. Затем переопределите метод canBecomeFirstResponder и переопределите переменную inputAccessoryView . Также не забудьте добавить self.myToolBar.removeFromSuperview() иначе xcode будет жаловаться.

 class ViewController: UIViewController { @IBOutlet var myToolBar: UIToolbar! override func canBecomeFirstResponder() -> Bool { return true } override var inputAccessoryView:UIView{ get{ return self.myToolBar } } override func viewDidLoad() { super.viewDidLoad() self.myToolBar.removeFromSuperview() } } 

Это отличное, простое в использовании решение с открытым исходным кодом от хороших людей в Slack: SlackTextViewController .

Вот как реализовать представление с закрепленной панелью инструментов в четыре этапа:

  1. Установите модуль в свой проект. ( http://cocoapods.org/?q=SlackTextViewController )
  2. Если вы пишете приложение в Swift, создайте заголовок для соединения между вашим кодом Swift и их классами Obj-C. Вот хорошее быстрое пошаговое руководство . (Подключаемый заголовок не нужен, как только классы будут переведены в Swift, кто-нибудь хочет сотрудничать с этим?)
  3. Создайте MessageViewController который наследуется от SLKTextViewController , не нужно писать больше кода, чем это:

     import Foundation import UIKit class MessageViewController: SLKTextViewController { required init(coder aDecoder: NSCoder!) { super.init(coder: aDecoder) } } 
  4. В Storyboard создайте контроллер просмотра, который наследуется от MessageViewController.
  5. Проверьте приложение на устройстве или эмуляторе, вы увидите красивый стыковочный текстовый блок, который также (в качестве бонуса) расширяется, когда пользователь пишет дополнительные строки текста.

Подкрепляет команду Slack для извлечения такого полезного контейнера.

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

 @property(nonatomic,assign)BOOL isFirstKeyboard; //workaround for keyboard bug @property(nonatomic,assign)BOOL isViewAppear; @property(nonatomic,strong)ChatBarView *chatView; //custom chat bar view @property(nonatomic,strong)UIView *footerPadView; //just to add some nice padding //////////////////////////////////////////////////////////////////////////////////////////////////// //in the view did load - (void)viewDidLoad { //more app specific code... self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive; self.chatView.textView.inputAccessoryView = self.chatView; } //////////////////////////////////////////////////////////////////////////////////////////////////// -(void)done { self.isFirstKeyboard = YES; [self.chatView.textView becomeFirstResponder]; } //////////////////////////////////////////////////////////////////////////////////////////////////// - (void) moveTextViewForKeyboard:(NSNotification*)aNotification up:(BOOL)up { if(!self.isViewAppear) return; //NSLog(@"keyboard is: %@", up ? @"UP" : @"Down"); if(!up && !self.isFirstKeyboard) [self performSelector:@selector(done) withObject:nil afterDelay:0.01]; else if(!up & self.isFirstKeyboard) { self.isFirstKeyboard = NO; [self.view addSubview:self.chatView]; CGRect frame = self.chatView.frame; frame.origin.y = self.view.frame.size.height - self.chatView.frame.size.height; self.chatView.frame = frame; } else { NSDictionary* userInfo = [aNotification userInfo]; NSTimeInterval animationDuration; UIViewAnimationCurve animationCurve; CGRect keyboardEndFrame; [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame]; // Animate up or down [UIView beginAnimations:nil context:nil]; if(up) [UIView setAnimationDuration:0.2]; else [UIView setAnimationDuration:0.3]; [UIView setAnimationCurve:animationCurve]; CGRect frame = self.footerPadView.frame; CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil]; if (up) frame.size.height = keyboardFrame.size.height - self.chatView.frame.size.height; else frame.size.height = 0; self.footerPadView.frame = frame; self.tableView.tableFooterView = self.footerPadView; [UIView commitAnimations]; } } //////////////////////////////////////////////////////////////////////////////////////////////////// - (void)keyboardWillShow:(NSNotification *)aNotification { [self moveTextViewForKeyboard:aNotification up:YES]; } //////////////////////////////////////////////////////////////////////////////////////////////////// - (void)keyboardWillHide:(NSNotification *)aNotification { [self moveTextViewForKeyboard:aNotification up:NO]; } //////////////////////////////////////////////////////////////////////////////////////////////////// 
  • Панель навигации iOS VS UIToolBar
  • Как добавить UIToolbar в NavigationController на раскадровке?
  • Панель действий во всех uiviewcontrollers в iOS
  • CNContactPickerViewController с UIToolbar
  • Как получить ширину кадра UIAlertController?
  • iOS11 UIToolBar Contentview
  • Как скрыть панель вкладок при перетаскивании, как приложение Safari?
  • Как скрыть панель навигации и панель инструментов прокруткой вниз? Swift (например, приложение myBridge)
  • Центрировать кнопку на UIToolBar
  • Элементы UIToolbar не отображаются в popover
  • Панель UINavigationController охватывает содержимое своего uiviewcontroller
  • Interesting Posts

    Масштабирование размера UIFont относительно размера экрана

    Как загрузить определенный образ из активов с помощью Swift

    Как добавить «http: //» в строку (если отсутствует)

    Как добавить изображение и ярлык в UINavigationBar как заголовок?

    Swift Error: Struct 'XX' должен быть полностью инициализирован до того, как элемент будет сохранен в

    Загрузите приложение iOS на сайт без отправки его в App Store

    Когда я использую prepareForSegue для передачи значения целевому контроллеру, возникают некоторые проблемы

    Проверить усечение в UILabel – iOS, Swift

    Пример использования AFNetworking для публикации XML?

    Удаление предупреждения о разрешении iOS для локальных уведомлений при запуске приложения в симуляторе

    NSCache для хранения изображений для UITableView

    Отключить WKWebView для открытия ссылок для перенаправления на приложения, установленные на моем iPhone

    Pull-to-refresh изменяет значение массива?

    "UITableViewCell? не имеет члена с именем 'textLabel'

    Как проверить, произошло ли нажатие на место в определенном месте

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.