представление контроллера модального представления, когда клавиатура активна

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

Могу ли я каким-либо образом представить модальную «над» клавиатуру, чтобы при ее увольнении клавиатура по-прежнему активна для поля, которое было первым ответчиком, прежде чем я представил модальный?

Прямо сейчас, клавиатура отклоняется, пока модальность появляется, и снова появляется, когда модаль отклоняется. Он выглядит неуклюжим для меня и отвлекающим. Хотелось бы упорядочить его и уменьшить количество анимации на экране.

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


Анимированный пример наложения нового UIWindow на существующий


У меня есть пример проекта на Github здесь , но основной процесс ниже.

  • Создайте новый класс UIViewController для вашего модального представления. Я назвал мой OverlayViewController . Настройте соответствующее представление по своему усмотрению. По вашему вопросу вам нужно передать некоторые параметры, поэтому я сделал делегатский протокол OverlayViewController и сделаю основной диспетчер представления основного окна (класс ViewController ) нашим делегатом.
 @protocol OverlayViewControllerDelegate <NSObject> @required - (void)optionChosen:(int)option; @end @interface OverlayViewController : UIViewController @property (nonatomic, weak) id<OverlayViewControllerDelegate> delegate; @end 
  • Добавьте некоторые вспомогательные свойства в наш оригинальный контроллер представления.
 @interface ViewController () <UIGestureRecognizerDelegate, UITextFieldDelegate, OverlayViewControllerDelegate> // The text field that responds to a double-tap. @property (weak) IBOutlet UITextField *textField; // A simple label that shows we received a message back from the overlay. @property (weak) IBOutlet UILabel *label; // Gesture recognizer for the text field @property (strong) UITapGestureRecognizer *doubleTapRecognizer; // The window that will appear over our existing one. @property (strong) UIWindow *overlayWindow; @end 
  • Добавьте UITapGestureRecognizer в свой UITextField .
 - (void)viewDidLoad { [super viewDidLoad]; // Perform any setup you need here // ... self.doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap)]; self.doubleTapRecognizer.numberOfTapsRequired = 2; self.doubleTapRecognizer.delegate = self; [self.textField addGestureRecognizer:self.doubleTapRecognizer]; } 
  • UITextField имеет встроенный распознаватель жестов, поэтому нам нужно позволить нескольким UIGestureRecognizer s работать одновременно.
 #pragma mark - UIGestureRecognizerDelegate - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } 
  • Это интересная часть. Когда запускается распознаватель жестов, создайте новый OverlayViewController UIWindow , назначьте свой OverlayViewController в качестве контроллера корневого представления и покажите его. Обратите внимание, что мы устанавливаем уровень окна на UIWindowLevelAlert . Вы не можете использовать UIWindowLevelNormal здесь, потому что клавиатура все еще будет впереди.
 - (void)handleDoubleTap { self.overlayWindow = [[UIWindow alloc] initWithFrame:self.view.window.frame]; [self.overlayWindow setWindowLevel:UIWindowLevelAlert]; OverlayViewController *overlayVC = [[OverlayViewController alloc] initWithNibName:@"OverlayViewController" bundle:nil]; self.overlayWindow.rootViewController = overlayVC; overlayVC.delegate = self; [self.overlayWindow makeKeyAndVisible]; } 
  • Окно оверлея теперь покрывает исходное окно и клавиатуру. Теперь пользователь может выбрать любые параметры, которые вы встроили в представление наложения. После того, как пользователь выберет опцию, ваш делегат должен предпринять любые действия, которые вы намерены, а затем отклоните окно оверлея.
 - (void)optionChosen:(int)option { // Your code goes here. Take action based on the option chosen. // ... // Dismiss the overlay self.overlayWindow = nil; } 
  • Окно оверлей должно исчезнуть, и ваше исходное окно должно появиться с клавиатурой в том же положении, что и раньше.

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

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

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

Для того, чтобы клавиатура UITextField or UITextView or UISearchBar видеть любой текст, принимающий поля, такие UITextField or UITextView or UISearchBar должны быть первым ответчиком, и они должны быть видимыми в представлении. Значение отвечающего представления должно быть в иерархии верхнего уровня в окне.

Если вам не нужен этот эффект, вместо представления ViewController вы можете добавить ViewController.view в качестве поднабора вашего self.view с анимацией.

У вас есть доступ к кадру клавиатуры в iOS.

Вам необходимо реализовать код для прослушивания уведомлений клавиатуры (например, UIKeyboardWillShowNotification и UIKeyboardWillChangeFrameNotification). Уведомление отправит вам информацию о кадре клавиатуры.

Giva взгляните на описание «Key Key Notification User Key Keys» в справочной системе Windows .

Вы найдете полезную для себя цель:

UIKeyboardBoundsUserInfoKey Ключ для объекта NSValue, содержащий CGRect, который идентифицирует прямоугольник границ клавиатуры в координатах окна. Этого значения достаточно для получения размера клавиатуры. Если вы хотите получить начало клавиатуры на экране (до или после анимации), используйте значения, полученные из словаря пользовательской информации, через константы UIKeyboardCenterBeginUserInfoKey или UIKeyboardCenterEndUserInfoKey.

С информацией о раме клавиатуры вы можете показать там модальный вид.

Просто добавьте жест привязки в текстовое поле и поле UITextfield * flagTextfield;

 UITapGestureRecognizer* doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(DoubleTapMethod:)]; doubleTap.numberOfTapsRequired = 2; [self.txtTest addGestureRecognizer:doubleTap]; -(void)DoubleTapMethod:(UITapGestureRecognizer *)gesture { [flagTextfield resignFirstResponder]; NSLog(@"DoubleTap detected"); //Set your logic on double tap of Textfield... //presents a modal view controller } - (void)textFieldDidBeginEditing:(UITextField *)textField{ flagTextfield = textfield; } 

Ответ @Rob Bajorek превосходный. Для iOS 9,10 есть небольшие изменения.
Вместо кода:

 [self.overlayWindow setWindowLevel:UIWindowLevelAlert]; [self.overlayWindow makeKeyAndVisible]; 

Введите следующий код:

 NSArray *windows = [[UIApplication sharedApplication] windows]; UIWindow *lastWindow = (UIWindow *)[windows lastObject]; [self.overlayWindow setWindowLevel:lastWindow.windowLevel + 1]; [self.overlayWindow setHidden:NO]; 
  • Скольжение в uitextfield
  • Изменение цвета заполнителя UITextField
  • Как отключить десятичный ключ на клавиатуре iOS
  • В iOS 6 - не работает в -viewWillAppear:
  • Если программный код UITextField установлен как программный, то вызывайте некоторые странные действия при редактировании текста
  • Установите цвет поля UITextfield на основе числового значения, используя оператор If в Objective-C
  • Как я могу включить / отключить клавиатуру Return Key вручную в Swift?
  • Переключение UITextField для отображения и скрытия в Swift
  • Отключить прикосновения, но не все пользовательское взаимодействие на UITextField
  • Как установить inputDelegate для UITextField?
  • Включить UIAlertAction из UIAlertController только после ввода
  • Interesting Posts

    iAd с Swift в SpriteKit

    SwiftyJson: объединение массива внутри массива

    Уведомление BLE, когда приложение не запущено

    Больше контроля над областью уведомлений iPhone для приложения стороннего календаря

    Swift – как получить последние 3 фотографии из библиотеки фотографий?

    Есть ли способ отслеживать загрузку отдельных ресурсов в uiwebview для ios

    Что такое «ошибка в __connection_block_invoke_2: соединение прерывается» в iOS?

    Мне нужно показать свое приложение в UIActivityViewController для всех приложений как расширение действия (по умолчанию)

    UIRefreshControl скрыт / затенен моей UINavigationController UINavigationBar

    Таймер NSTimerWithTimeInterval: не работает

    Как остановить аудиозапись AirPlay с помощью AVPlayer?

    Поиск в поисковой строке

    Эффект цвета градиента на CAShapeLayer

    NSOperation в iOS – Как обрабатывать циклы и вложенный вызов NSOperation для получения изображений

    Как фиксировать текущее значение переменной для блока

    Давайте будем гением компьютера.