У меня довольно много элементов управления, которые разбросаны по многим ячейкам таблицы в моей таблице, и мне было интересно, есть ли более простой способ отклонить клавиатуру, не пробирая все мои элементы управления и не оставляя их всех в качестве первого ответчика. Я думаю, вопрос в том, как.. Как бы получить текущий первый ответчик на клавиатуре?
Легкий способ убрать клавиатуру?
Ответ 1
Пытаться:
[self.view endEditing:YES];
Ответ 2
Вы можете заставить текущее редактируемое представление сбрасывать свой статус первого ответчика с помощью [view endEditing:YES]
. Это скрывает клавиатуру.
В отличие от -[UIResponder resignFirstResponder]
, -[UIView endEditing:]
выполнит поиск в подзонах, чтобы найти текущего первого ответчика. Таким образом, вы можете отправить его на верхний уровень (например, self.view
в UIViewController
), и он пойдет правильно.
(Этот ответ ранее включал несколько других решений, которые также работали, но были более сложными, чем это необходимо. Я удалил их, чтобы избежать путаницы.)
Ответ 3
Вы можете отправить нулевое целевое действие в приложение, оно в любой момент уйдет с первого ответчика, не беспокоясь о том, какой вид в настоящее время имеет статус первого ответчика.
Objective-C:
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
Swift 3.0:
UIApplication.shared.sendAction(#selector(resignFirstResponder), to: nil, from: nil, for: nil)
В Mac OS X для команд меню используются целые действия Nil, и здесь их использование на iOS.
Ответ 4
Честно говоря, я не сумасшедший о любом из предлагаемых здесь решений. Я нашел хороший способ использовать TapGestureRecognizer, который, как мне кажется, лежит в основе вашей проблемы: когда вы нажимаете на что-либо помимо клавиатуры, отпустите клавиатуру.
-
В viewDidLoad зарегистрируйтесь, чтобы получать уведомления о клавиатуре и создать UITapGestureRecognizer:
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil]; [nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil]; tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapAnywhere:)];
-
Добавьте кнопку show/hide для отображения клавиатуры. Там вы добавляете и удаляете TapGestureRecognizer в UIView, который должен отклонять клавиатуру при нажатии. Примечание. Вам не нужно добавлять его ко всем суб-представлениям или элементам управления.
-(void) keyboardWillShow:(NSNotification *) note { [self.view addGestureRecognizer:tapRecognizer]; } -(void) keyboardWillHide:(NSNotification *) note { [self.view removeGestureRecognizer:tapRecognizer]; }
-
TapGestureRecognizer будет вызывать вашу функцию, когда она будет нажата, и вы можете отменить клавиатуру следующим образом:
-(void)didTapAnywhere: (UITapGestureRecognizer*) recognizer { [textField resignFirstResponder]; }
Самое приятное в этом решении состоит в том, что он только фильтрует для Taps, а не swipes. Поэтому, если у вас есть прокрутка содержимого над клавиатурой, swipes все равно будет прокручиваться и покидать клавиатуру. Удалив распознаватель жестов после того, как клавиатура ушла, будущие краны на вашем изображении обрабатываются нормально.
Ответ 5
Это решение, чтобы клавиатура ушла, когда нажата return
в любом текстовом поле, добавив код в одном месте (так что не нужно добавлять обработчик для каждого текстового поля):
рассмотрите этот сценарий:
У меня есть viewcontroller
с двумя текстовыми полями (имя пользователя и пароль).
и viewcontroller
реализует протокол UITextFieldDelegate
Я делаю это в viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
username.delegate = self;
password.delegate = self;
}
а viewcontroller реализует необязательный метод как
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
и независимо от текстового поля, в котором вы находитесь, как только я нажимаю return
на клавиатуре, он отклоняется!
В вашем случае то же самое будет работать до тех пор, пока вы установите все делегат текстового поля на себя и реализуете textFieldShouldReturn
Ответ 6
Лучший подход - иметь что-то "украсть" статус первого ответчика.
Так как UIApplication является подклассом UIResponder, вы можете попробовать:
[[UIApplication sharedApplication] becomeFirstResponder]
[[UIApplication sharedApplication] resignFirstResponder]
В противном случае создайте новый UITextField с фреймом нулевого размера, добавьте его в представление где-нибудь и сделайте что-нибудь подобное (за ним последует отставка).
Ответ 7
Убейте это в каком-то классе утилиты.
+ (void)dismissKeyboard {
[self globalResignFirstResponder];
}
+ (void) globalResignFirstResponder {
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
for (UIView * view in [window subviews]){
[self globalResignFirstResponderRec:view];
}
}
+ (void) globalResignFirstResponderRec:(UIView*) view {
if ([view respondsToSelector:@selector(resignFirstResponder)]){
[view resignFirstResponder];
}
for (UIView * subview in [view subviews]){
[self globalResignFirstResponderRec:subview];
}
}
Ответ 8
@Николас Райли и @Кенделл Гельмстеттер Гельн и @cannyboy:
Абсолютно блестящий!
Спасибо.
Учитывая ваши советы и советы других в этой теме, это то, что я сделал:
Как выглядит:
[[self appDelegate] dismissKeyboard];
(примечание: я добавил appDelegate как дополнение к NSObject, чтобы я мог использовать где угодно на что угодно)
Что это выглядит под капотом:
- (void)dismissKeyboard
{
UITextField *tempTextField = [[[UITextField alloc] initWithFrame:CGRectZero] autorelease];
tempTextField.enabled = NO;
[myRootViewController.view addSubview:tempTextField];
[tempTextField becomeFirstResponder];
[tempTextField resignFirstResponder];
[tempTextField removeFromSuperview];
}
ИЗМЕНИТЬ
Поправка к моему ответу включала tempTextField.enabled = NO;
. Отключение текстового поля предотвратит отправку уведомлений клавиатуры UIKeyboardWillShowNotification
и UIKeyboardWillHideNotification
, если вы полагаетесь на эти уведомления в своем приложении.
Ответ 9
Много слишком сложных ответов здесь, возможно, потому, что это нелегко найти в документации iOS. Джозеф Х имел это прямо выше:
[[view window] endEditing:YES];
Ответ 10
Быстрый отзыв о том, как убрать клавиатуру в iOS, когда пользователь прикасается к экрану вне UITextField или клавиатуры. Учитывая, сколько недвижимости клавиатура iOS может принять, имеет смысл иметь простой и интуитивно понятный способ, чтобы ваши пользователи отклонили клавиатуру.
Здесь ссылка
Ответ 11
Даже проще, чем Meagar ответить
переписать touchesBegan:withEvent:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[textField resignFirstResponder];`
}
Это будет dismiss the keyboard
, когда вы коснетесь где-нибудь в background
.
Ответ 12
Вот что я использую в своем коде. Он работает как шарм!
В yourviewcontroller.h добавьте:
@property (nonatomic) UITapGestureRecognizer *tapRecognizer;
Теперь в файле .m добавьте это в свою функцию ViewDidLoad:
- (void)viewDidLoad {
//Keyboard stuff
tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapAnywhere:)];
tapRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapRecognizer];
}
Кроме того, добавьте эту функцию в файл .m:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
Ответ 13
В вашем представлении файл заголовка контроллера добавьте <UITextFieldDelegate>
в определение интерфейса вашего контроллера, чтобы он соответствовал протоколу делегатов UITextField...
@interface someViewController : UIViewController <UITextFieldDelegate>
... В файле реализации контроллера (.m) добавьте следующий метод или код внутри него, если у вас уже есть метод viewDidLoad...
- (void)viewDidLoad
{
// Do any additional setup after loading the view, typically from a nib.
self.yourTextBox.delegate = self;
}
... Затем привяжите yourTextBox к вашему фактическому текстовому полю
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField
{
if (theTextField == yourTextBox) {
[theTextField resignFirstResponder];
}
return YES;
}
Ответ 14
Вы должны отправить endEditing:
в рабочее окно, являющееся подклассом UIView
[[UIApplication sharedApplication].windows.firstObject endEditing:NO];
Ответ 15
Лучший способ убрать клавиатуру из UITableView и UIScrollView:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
Ответ 16
В быстром 3 вы можете сделать следующее
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
Ответ 17
Ответ Джереми для меня не совсем сработал, я думаю, потому что у меня был стек навигации в виде табуляции с модальным диалогом поверх него. Я использую следующее прямо сейчас, и он работает для меня, но ваш пробег может отличаться.
// dismiss keyboard (mostly macro)
[[UIApplication sharedApplication].delegate dismissKeyboard]; // call this in your to app dismiss the keybaord
// --- dismiss keyboard (in indexAppDelegate.h) (mostly macro)
- (void)dismissKeyboard;
// --- dismiss keyboard (in indexAppDelegate.m) (mostly macro)
// do this from anywhere to dismiss the keybard
- (void)dismissKeyboard { // from: http://stackoverflow.com/questions/741185/easy-way-to-dismiss-keyboard
UITextField *tempTextField = [[UITextField alloc] initWithFrame:CGRectZero];
UIViewController *myRootViewController = <#viewController#>; // for simple apps (INPUT: viewController is whatever your root controller is called. Probably is a way to determine this progragrammatically)
UIViewController *uivc;
if (myRootViewController.navigationController != nil) { // for when there is a nav stack
uivc = myRootViewController.navigationController;
} else {
uivc = myRootViewController;
}
if (uivc.modalViewController != nil) { // for when there is something modal
uivc = uivc.modalViewController;
}
[uivc.view addSubview:tempTextField];
[tempTextField becomeFirstResponder];
[tempTextField resignFirstResponder];
[tempTextField removeFromSuperview];
[tempTextField release];
}
Ответ 18
Вам также может потребоваться переопределить UIViewController disablesAutomaticKeyboardDismissal, чтобы заставить это работать в некоторых случаях. Это может потребоваться для UINavigationController, если у вас есть.
Ответ 19
Подкласс ваших текстовых полей..., а также текстовых просмотров
В подклассе введите этот код..
-(void)conformsToKeyboardDismissNotification{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissKeyBoard) name:KEYBOARD_DISMISS object:nil];
}
-(void)deConformsToKeyboardDismissNotification{
[[NSNotificationCenter defaultCenter] removeObserver:self name:KEYBOARD_DISMISS object:nil];
}
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self resignFirstResponder];
}
В текстовом поле делегаты (аналогично для делегатов textview)
-(void)textFieldDidBeginEditing:(JCPTextField *)textField{
[textField conformsToKeyboardDismissNotification];
}
- (void)textFieldDidEndEditing:(JCPTextField *)textField{
[textField deConformsToKeyboardDismissNotification];
}
Все настройки.. Теперь просто отправьте уведомление из любого места в своем коде. Он отменит любую клавиатуру.
Ответ 20
И в быстрой мы можем сделать
UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)
Ответ 21
Чтобы закрыть клавиатуру после появления клавиатуры, есть 2 случая,
-
когда UITextField внутри UIScrollView
-
когда UITextField вне UIScrollView
2. Когда UITextField находится вне UIScrollView переопределить метод в вашем подклассе UIViewController
вы также должны добавить делегат для всех UITextView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
- В представлении прокрутки нажатие на внешнюю сторону не будет запускать какое-либо событие, поэтому в этом случае используйте указатель дескриптора жесткости, Перетащите UITapGesture для прокрутки и создайте для него IBAction.
чтобы создать IBAction, нажмите ctrl + щелкнуть UITapGesture и перетащить его в .h файл viewcontroller.
Здесь я назвал tappedEvent именем моего действия
- (IBAction)tappedEvent:(id)sender {
[self.view endEditing:YES]; }
указанная информация была получена из следующей ссылки, пожалуйста, обратитесь за дополнительной информацией или свяжитесь со мной, если вы не понимаете данные abouve.
http://samwize.com/2014/03/27/dismiss-keyboard-when-tap-outside-a-uitextfield-slash-uitextview/
Ответ 22
Я ненавижу, что нет "глобального" способа программно упускать клавиатуру без использования частных вызовов API. Зачастую у меня есть необходимость отбрасывать клавиатуру программно, не зная, какой объект является первым ответчиком. Я прибегал к проверке self
с помощью API-интерфейса Objective-C, перечисляя все его свойства, вытягивая те, которые имеют тип UITextField
, и отправляет им сообщение resignFirstResponder
.
Это не должно быть так сложно сделать...
Ответ 23
Это некрасиво, но так, как я ухожу в отставку первогоResponder, когда я не знаю, что это за ответчик:
Создайте UITextField, либо в IB, либо программно. Сделайте это Скрытым. Свяжите его с кодом, если вы сделали его в IB. Затем, когда вы хотите отклонить клавиатуру, вы переключите ответчик на невидимое текстовое поле и немедленно смирите его:
[self.invisibleField becomeFirstResponder];
[self.invisibleField resignFirstResponder];
Ответ 24
Вы можете рекурсивно выполнять итерацию через subviews, хранить массив всех UITextFields, а затем прокручивать их и оставлять в силе все.
Не очень хорошее решение, особенно если у вас много подзаголовков, но для простых приложений он должен сделать трюк.
Я решил это намного сложнее, но гораздо более результативно, но используя singleton/manager для механизма анимации своего приложения, и в любое время, когда текстовое поле стало ответчиком, я бы назначил его статическому который был бы сметен (подал в отставку) на основе некоторых других событий... его почти невозможно объяснить в абзаце.
Будьте изобретательны, мне понадобилось всего 10 минут, чтобы продумать это для моего приложения после того, как я нашел этот вопрос.
Ответ 25
проще всего вызвать метод
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if(![txtfld resignFirstResponder])
{
[txtfld resignFirstResponder];
}
else
{
}
[super touchesBegan:touches withEvent:event];
}
Ответ 26
Несколько более надежный метод, который мне нужно было использовать в последнее время:
- (void) dismissKeyboard {
NSArray *windows = [UIApplication sharedApplication].windows;
for(UIWindow *window in windows) [window endEditing:true];
// Or if you're only working with one UIWindow:
[[UIApplication sharedApplication].keyWindow endEditing:true];
}
Я обнаружил, что некоторые из других "глобальных" методов не работают (например, UIWebView
и WKWebView
отказались уйти в отставку).
Ответ 27
Добавьте указатель жесты на ваш взгляд. И определите его ibaction
ваш .m файл будет похож на
- (IBAction)hideKeyboardGesture:(id)sender {
NSArray *windows = [UIApplication sharedApplication].windows;
for(UIWindow *window in windows) [window endEditing:true];
[[UIApplication sharedApplication].keyWindow endEditing:true];
}
Это сработало для меня
Ответ 28
Да, endEditing - лучший вариант. И From iOW 7.0, UIScrollView
имеет классную функцию, чтобы отменить клавиатуру при взаимодействии с видом прокрутки. Для этого вы можете установить свойство keyboardDismissMode
UIScrollView
.
Установите режим отключения клавиатуры как:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
У него мало других типов. Посмотрите на этот яблочный документ.
Ответ 29
В быстрой:
self.view.endEditing(true)
Ответ 30
Вы должны использовать один из этих методов,
[self.view endEditing:YES];
или
[self.textField resignFirstResponder];