Простой способ уволить клавиатуру? - PullRequest
373 голосов
/ 12 апреля 2009

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

Ответы [ 31 ]

787 голосов
/ 14 сентября 2010

Попробуйте:

[self.view endEditing:YES];
126 голосов
/ 12 апреля 2009

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

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

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

90 голосов
/ 05 января 2013

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

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.

56 голосов
/ 28 июня 2011

Если честно, я не в восторге от любого из предложенных здесь решений. Я нашел хороший способ использовать 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];
    }
    

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

22 голосов
/ 24 июня 2009

Это решение, позволяющее отключить клавиатуру при нажатии 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

14 голосов
/ 13 апреля 2009

Лучше всего, чтобы кто-то «украл» статус первого респондента.

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

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

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

7 голосов
/ 24 июня 2011

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

+ (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];
    }
}
6 голосов
/ 14 сентября 2010

@ Николас Райли и @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];
}

EDIT

Поправка к моему ответу включена tempTextField.enabled = NO;. Отключение текстового поля предотвратит отправку уведомлений с клавиатуры UIKeyboardWillShowNotification и UIKeyboardWillHideNotification, если вы будете использовать эти уведомления во всем приложении.

5 голосов
/ 30 марта 2012

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

[[view window] endEditing:YES];
4 голосов
/ 17 сентября 2011

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

Вот ссылка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...