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



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

578   30  

30 ответов:

попробуй:
[self.view endEditing:YES];

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

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

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

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

Цель-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)

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 в клавиатуре, он получает уволен!

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

@Nicholas Riley & @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

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

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

[[view window] endEditing:YES];

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

здесь ссылка

даже проще, чем ответ Meagar

перезаписать touchesBegan:withEvent:

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

это dismiss the keyboardкогда вы касаетесь в любом месте на background.

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

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

В yourviewcontroller.ч добавить:

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

кроме того, добавьте эту функцию в .файл м:

- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
    [self.view endEditing:YES];
}

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

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

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

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag

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

UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: 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://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];

}

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

подкласс текстовых полей... а также элемента

в подкласс ставим этот код..

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

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

и в Swift мы можем сделать

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

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

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

  2. когда UITextField вне UIScrollView

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

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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
}
  1. на прокрутка вид, нажав снаружи не будет стрелять любое событие, так что в этом случае используйте распознаватель жестов крана, Перетащите a 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/

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

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

это не очень красиво, но то, как я ухожу в отставку firstResponder, когда я не знаю, что такое ответчик:

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

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

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

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

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

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

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

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

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

ваш .файл м будет как

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

это сработало для меня

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

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

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag

Он имеет несколько других типов. Взгляните на это документ apple.

в swift:

self.view.endEditing(true)

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

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

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

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

[self.view endEditing:YES];

или

[self.textField resignFirstResponder];

Comments

    Ничего не найдено.