Легкий способ убрать клавиатуру?

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

Ответ 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];