Простой способ уволить клавиатуру?

У меня довольно много элементов управления, разбросанных по многим ячейкам таблицы в моей таблице, и мне было интересно, есть ли более простой способ уволить клавиатуру без необходимости циклически перебирать все мои элементы управления и отказываться от них всех в качестве первого респондента. Я предполагаю, что вопрос.. Как бы я получить текущий первый ответчик на клавиатуре?

31 ответ

Решение

Пытаться:
[self.view endEditing:YES];

Вы можете принудительно изменить вид, редактируемый в настоящее время, чтобы изменить статус первого респондента с [view endEditing:YES], Это скрывает клавиатуру.

В отличие от -[UIResponder resignFirstResponder], -[UIView endEditing:] будет искать в подпредставлениях, чтобы найти текущего первого респондента. Таким образом, вы можете отправить его на верхнем уровне просмотра (например, self.view в UIViewController) и это будет правильно делать.

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

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

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 для команд меню, и вот их использование в iOS.

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

  1. В 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:)];
    
  2. Добавить клавиатуру показать / скрыть респондентов. Там вы добавляете и удаляете TapGestureRecognizer в UIView, который должен отклонять клавиатуру при нажатии. Примечание. Нет необходимости добавлять его во все вложенные представления или элементы управления.

    -(void) keyboardWillShow:(NSNotification *) note {
        [self.view addGestureRecognizer:tapRecognizer];
    }
    
    -(void) keyboardWillHide:(NSNotification *) note
    {
        [self.view removeGestureRecognizer:tapRecognizer];
    }
    
  3. TapGestureRecognizer будет вызывать вашу функцию, когда он получает нажатие, и вы можете отклонить клавиатуру следующим образом:

    -(void)didTapAnywhere: (UITapGestureRecognizer*) recognizer {    
        [textField resignFirstResponder];
    }
    

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

Это решение, чтобы заставить клавиатуру уйти при нажатии 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 в клавиатуре это уволено!

В вашем случае то же самое будет работать, если вы установите для всех делегатов текстового поля значение self и реализуете textFieldShouldReturn

Лучше подходить, чтобы что-то "украло" статус первого респондента.

Поскольку UIApplication является подклассом UIResponder, вы можете попробовать:

[[UIApplication sharedApplication] becomeFirstResponder]
[[UIApplication sharedApplication] resignFirstResponder]

В противном случае создайте новый UITextField с фреймом нулевого размера, добавьте его где-нибудь в представление и сделайте что-то подобное (переходите в отставку).

Убери это в каком-нибудь служебном классе.

+ (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];
    }
}

@ Николас Райли & @Kendall Helmstetter Geln & @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 уведомления от клавиатуры от отправки, если вы полагаетесь на эти уведомления во всем приложении.

Вот что я использую в своем коде. Отлично работает!

В 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];
}

Здесь много слишком сложных ответов, возможно, потому, что это не так легко найти в документации по iOS. Иосиф-Х имел это прямо выше:

[[view window] endEditing:YES];

Даже проще, чем ответ Мигар

затирать touchesBegan:withEvent:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [textField resignFirstResponder];`
}

Это будет dismiss the keyboardкогда вы касаетесь где-либо в background,

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

Вот ссылка

Вы должны отправить endEditing: чтобы рабочее окно являлось подклассом UIView

[[UIApplication sharedApplication].windows.firstObject endEditing:NO];

Лучший способ отклонить клавиатуру из UITableView и UIScrollView:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag

В заголовочный файл вашего контроллера добавить <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;
}

В Swift 3 вы можете сделать следующее

UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)

Подкласс ваши текстовые поля... а также текстовые представления

В подклассе положить этот код..

-(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];
}

Все готово.. Теперь просто отправьте уведомление из любого места в вашем коде. Он подаст в отставку любую клавиатуру.

И в кратчайшие сроки мы можем сделать

UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)

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

 // 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://stackru.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];

}

Чтобы закрыть клавиатуру после ее появления, есть 2 случая:

  1. когда UITextField находится внутри UIScrollView

  2. когда UITextField находится вне UIScrollView

2. когда UITextField находится вне UIScrollView, переопределите метод в вашем подклассе UIViewController

Вы также должны добавить делегат для всех UITextView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
}
  1. В режиме прокрутки касание снаружи не вызовет никакого события, поэтому в этом случае используйте Распознаватель жестов касания, перетащите UITapGesture для представления прокрутки и создайте для него IBAction.

чтобы создать IBAction, нажмите Ctrl+ щелкните UITapGesture и перетащите его в.h файл viewcontroller.

Здесь я назвал tappedEvent в качестве имени моего действия

- (IBAction)tappedEvent:(id)sender {
      [self.view endEditing:YES];  }

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

http://samwize.com/2014/03/27/dismiss-keyboard-when-tap-outside-a-uitextfield-slash-uitextview/

Вам также может понадобиться переопределить UIViewController disablesAutomaticKeyboardDismissal, чтобы в некоторых случаях это работало. Это, возможно, должно быть сделано на UINavigationController, если у вас есть.

Вы должны использовать один из этих методов,

[self.view endEditing:YES];

или же

[self.textField resignFirstResponder];

Вы можете рекурсивно перебирать подпредставления, сохранять массив всех UITextFields, а затем перебирать их и оставлять их все.

Не очень хорошее решение, особенно если у вас много подпредставлений, но для простых приложений это должно сработать.

Я решил это гораздо более сложным, но гораздо более производительным способом, но с использованием синглтона / менеджера для механизма анимации моего приложения, и каждый раз, когда текстовое поле становилось отвечающим, я назначал его статическому элементу, который получал бы подметил (подал в отставку) на основе некоторых других событий... это почти невозможно для меня объяснить в параграфе.

Будьте изобретательны, мне понадобилось всего 10 минут, чтобы обдумать это для моего приложения после того, как я нашел этот вопрос.

Самый простой способ - вызвать метод

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    if(![txtfld resignFirstResponder])
    {
        [txtfld resignFirstResponder];
    }
    else
    {

    }
    [super touchesBegan:touches withEvent:event];
}

В скором времени:

self.view.endEditing(true)

Это не красиво, но то, как я оставляю firstResponder, когда я не знаю, что это за ответчик:

Создайте UITextField, либо в IB, либо программно. Сделать это скрытым Свяжите это с вашим кодом, если вы сделали это в IB. Затем, когда вы хотите убрать клавиатуру, вы переключаете респондент в невидимое текстовое поле и немедленно отмените его:

  [self.invisibleField becomeFirstResponder];
  [self.invisibleField resignFirstResponder];

Немного более надежный метод, который мне нужно было использовать недавно:

- (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 отказался уйти в отставку).

Я ненавижу, что не существует "глобального" способа программно отключить клавиатуру без использования частных вызовов API. Часто мне нужно программно отмахиваться от клавиатуры, не зная, какой объект является первым респондентом. Я прибег к проверке self используя API-интерфейс Objective-C, перечисляя все его свойства, извлекая те, которые имеют тип UITextFieldи отправив им resignFirstResponder сообщение.

Это не должно быть так сложно сделать это...

Добавьте распознаватель жестов касанием к своему виду. И определите его ibaction

ваш.m файл будет похож

    - (IBAction)hideKeyboardGesture:(id)sender {
    NSArray *windows = [UIApplication sharedApplication].windows;
    for(UIWindow *window in windows) [window endEditing:true];
    [[UIApplication sharedApplication].keyWindow endEditing:true];
}

Это работает для меня

Да, endEditing - лучший вариант. И из iOW 7.0, UIScrollView имеет классную функцию, чтобы отклонить клавиатуру при взаимодействии с видом прокрутки. Для достижения этого вы можете установить keyboardDismissMode собственностью UIScrollView,

Установите режим отклонения клавиатуры как:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag

У него есть несколько других типов. Посмотрите на этот яблочный документ.

Другие вопросы по тегам