Iphone, отключайте клавиатуру при касании вне UITextField

Мне интересно, как заставить клавиатуру исчезнуть, когда пользователь коснется вне UITextField?

384
задан jonepatr 15 марта '11 в 3:31
источник поделиться

32 ответов

  • 1
  • 2

Вам нужно добавить UITapGestureRecogniser и назначить его представлению, а затем вызвать отставку первого ответчика на UITextField на этом селекторе.

Код:

В представленииDidLoad

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];

[self.view addGestureRecognizer:tap];

В приглашении:

-(void)dismissKeyboard 
{
    [aTextField resignFirstResponder];
}

(Где aTextField - текстовое поле, отвечающее за клавиатуру)

версия Swift 3 выглядит так:

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)

Для функции "Отклонить"

func dismissKeyboard (_ sender: UITapGestureRecognizer) {
    aTextField.resignFirstResponder()
}
682
ответ дан Jensen2k 15 марта '11 в 3:36
источник поделиться

Я отбросил несколько ответов.

Используйте ivar, который инициализируется во время viewDidLoad:

UIGestureRecognizer *tapper;

- (void)viewDidLoad
{
    [super viewDidLoad];
    tapper = [[UITapGestureRecognizer alloc]
                initWithTarget:self action:@selector(handleSingleTap:)];
    tapper.cancelsTouchesInView = NO;
    [self.view addGestureRecognizer:tapper];
}

Откажитесь от того, что редактируется в данный момент:

- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
    [self.view endEditing:YES];
}
159
ответ дан drewish 24 июля '12 в 6:01
источник поделиться

Проверьте это, это был бы самый простой способ сделать это,

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
      [self.view endEditing:YES];// this will do the trick
}

или

Эта библиотека будет обрабатывать, включая прокрутку полосы прокрутки, коснитесь места, чтобы скрыть клавиатуру и т.д.

https://github.com/michaeltyson/TPKeyboardAvoiding

95
ответ дан Prasad De Zoysa 20 июня '12 в 13:52
источник поделиться

Я вижу, что у некоторых людей возникают проблемы с использованием метода UITapGestureRecognizer. Самый простой способ, которым я выполнил эту функциональность, сохраняя при этом неизменное поведение кнопки, - добавить только одну строку в ответ @Jensen2k:

[tap setCancelsTouchesInView:NO];

Это позволило моим существующим кнопкам по-прежнему работать без использования метода @Dmitry Sitnikov.

Читайте об этом свойстве здесь (ищите "CancelsTouchesInView" ): Ссылка на класс UIGestureRecognizer

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

79
ответ дан Qiao Yi 03 февр. '12 в 20:21
источник поделиться

Лучше сделать ваш UIView экземпляром UIControl (в построителе интерфейса), а затем подключить их событие "Touch Up Inside", чтобы убрать методKeyboard. Этот метод IBAction будет выглядеть следующим образом:

- (IBAction)dismissKeyboard:(id)sender {
    [aTextBox resignFirstResponder];
}
50
ответ дан Dmitry Sitnikov 04 авг. '11 в 11:43
источник поделиться

Быстрая версия, это работает в сочетании с другими элементами (например, UIButton или другой UITextField):

override func viewDidLoad() {
    super.viewDidLoad()

    let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
    tapper.cancelsTouchesInView = false
    view.addGestureRecognizer(tapper)
}
24
ответ дан Rob 06 янв. '15 в 18:05
источник поделиться

Как насчет этого: я знаю, что это старый пост. Это может помочь кому-то:)

-(void)touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event {   
    NSArray *subviews = [self.view subviews];
    for (id objects in subviews) {
        if ([objects isKindOfClass:[UITextField class]]) {
            UITextField *theTextField = objects;
            if ([objects isFirstResponder]) {
                [theTextField resignFirstResponder];
            }
        } 
    }
}
14
ответ дан Mr H 04 окт. '11 в 8:42
источник поделиться

Это хорошее общее решение:

Objective-C:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];    
}

Swift:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    self.view.endEditing(true)
}

На основе решения @icodebuster: qaru.site/questions/17499/...

10
ответ дан eduludi 10 окт. '14 в 13:16
источник поделиться

Я думаю, что самый простой (и лучший) способ сделать это - подклассировать глобальное представление и использовать метод hitTest: withEvent для прослушивания любого касания. Прикосновения на клавиатуре не регистрируются, поэтому hitTest: withEvent вызывается только при касании/прокрутке/прокрутке/ущемлении... в другом месте, затем вызовите [self endEditing: YES].

Это лучше, чем использование touchhesBegan, потому что touchsBegan не вызывается, если вы нажмете кнопку над представлением. Это лучше, чем UITapGestureRecognizer, который не может распознать жест прокрутки, например. Это также лучше, чем использование тусклого экрана, потому что в сложном и динамическом пользовательском интерфейсе вы не можете помещать тусклый экран где угодно. Кроме того, он не блокирует другие действия, вам не нужно дважды нажать, чтобы выбрать кнопку снаружи (например, в случае UIPopover).

Кроме того, это лучше, чем вызов [textField resignFirstResponder], потому что на экране может быть много текстовых полей, поэтому это работает для всех.

9
ответ дан Enzo Tran 05 янв. '12 в 19:10
источник поделиться

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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];    
}

(from Как отключить клавиатуру, когда пользователь коснулся другой области вне текстового поля?)

6
ответ дан Maggie Phillips 11 марта '16 в 8:56
источник поделиться

Если бы я понял, что вы хотите сменить клавиатуру, нажав на outSide textfield, но у вас нет ссылки на ваш textfield.

Попробуйте это;

  • Возьмите глобальный текстовый фильтр, позвоните ему reftextField
  • Теперь в textFieldDidBeginEditing установите текстовое поле с привязкой в ​​

    - (void) textFieldDidBeginEditing:(UITextField *)textField{
        reftextField = textField;
    }
    
  • Теперь вы можете с радостью использовать любые часы кнопок (добавление прозрачной кнопки при редактировании рекомендуется редактировать)

    - (void)dismissKeyboard {
          [reftextField resignFirstResponder];
    }
    
  • Или для отставки кнопки "Готово" попробуйте это.

    //for resigning on done button    
    - (BOOL) textFieldShouldReturn:(UITextField *)textField{
        [textField resignFirstResponder];
        return YES;
    }
    
5
ответ дан rptwsthi 01 марта '13 в 17:51
источник поделиться

Вы можете использовать метод UITapGestureRecongnizer для отклонения клавиатуры, выйдя за пределы UITextField. Используя этот метод всякий раз, когда пользователь будет выходить за пределы UITextField, клавиатура будет отключена. Ниже приведен фрагмент кода для его использования.

 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
                                   initWithTarget:self
                                   action:@selector(dismissk)];

    [self.view addGestureRecognizer:tap];


//Method
- (void) dismissk
{
    [abctextfield resignFirstResponder];
    [deftextfield resignFirstResponder];

}
4
ответ дан Nirzar Gandhi 25 сент. '15 в 16:37
источник поделиться

Вы можете сделать это, используя раскадровку в XCode 6 и выше:


Создайте действие, чтобы скрыть клавиатуру

Добавьте это в заголовочный файл класса, используемого вашим ViewController:

@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>

- (IBAction)dissmissKeyboardOnTap:(id)sender;

@end

Затем добавьте это в файл реализации того же ViewController:

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

Теперь это будет одно из "полученных действий" для вашей сцены раскадровки (т.е. ViewController):

введите описание изображения здесь


Подключить действие к пользовательскому событию

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

Важно. Вам нужно преобразовать "UIView", который содержится в вашем раскадровке, в UIControl, чтобы он мог получать события. Выберите представление из иерархии сцены диспетчера просмотров:

введите описание изображения здесь

... и измените его класс:

введите описание изображения здесь

Теперь перетащите из маленького круга рядом с "полученным действием" для вашей сцены на "пустую" часть вашей сцены (на самом деле вы перетаскиваете "Полученное действие" в UIControl). Вам будет показан список событий, которые вы можете связать с вашим действием:

введите описание изображения здесь

Выберите параметр "коснуться внутри". Теперь вы подключили IBAction, который вы создали, к действию пользователя, касающегося клавиатуры. Когда пользователь отключит клавиатуру, он теперь будет скрыт.

(ПРИМЕЧАНИЕ. Чтобы связать действие с событием, вы также можете перетащить из полученного действия непосредственно в UIControl в иерархии контроллеров View. Он отображается как "Control" в иерархии.)

4
ответ дан Chris Halcrow 16 окт. '15 в 4:47
источник поделиться

Если представление встроено во все в UIScrollView, вы можете использовать следующее:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

Первый будет анимировать клавиатуру с экрана, когда прокручивается табличное представление, а позже будет скрывать клавиатуру, как приложение "Акции".

Обратите внимание, что они доступны на iOS 7.0 или выше.

3
ответ дан Joe Masilotti 14 авг. '14 в 16:05
источник поделиться

Вы можете создать категорию для UiView и переопределить meathod touchsBegan следующим образом.

Он отлично работает для меня. И это централизованное решение этой проблемы.

#import "UIView+Keyboard.h"
@implementation UIView(Keyboard)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.window endEditing:true];
    [super touchesBegan:touches withEvent:event];
}
@end
3
ответ дан Hiren 29 окт. '15 в 12:12
источник поделиться

Просто добавьте в список здесь мою версию о том, как убрать клавиатуру на внешнем прикосновении.

viewDidLoad:

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];

Anywhere:

-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
    [textFieldName resignFirstResponder];
    puts("Dismissed the keyboard");
}
3
ответ дан John Riselvato 17 июля '12 в 3:50
источник поделиться

Здесь много замечательных ответов об использовании UITapGestureRecognizer - все это сломает кнопку UITextField clear (X). Решение заключается в подавлении распознавателя жестов через его делегата:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    BOOL touchViewIsButton = [touch.view isKindOfClass:[UIButton class]];
    BOOL touchSuperviewIsTextField = [[touch.view superview] isKindOfClass:[UITextField class]];
    return !(touchViewIsButton && touchSuperviewIsTextField);
}

Это не самое надежное решение, но оно работает для меня.

3
ответ дан skedastik 22 нояб. '13 в 6:59
источник поделиться

Быстрая версия ответа @Jensen2k:

let gestureRecognizer : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: "dismissKeyboard")
self.addGestureRecognizer(gestureRecognizer)

func dismissKeyboard() {
    aTextField.resignFristResponder()
}

Один вкладыш

self.view.addTapGesture(UITapGestureRecognizer.init(target: self, action: "endEditing:"))
3
ответ дан Syed Asad Ali 22 апр. '16 в 13:16
источник поделиться

Я использовал пример Барри для моей новой разработки. Это здорово! но я должен был внести небольшое изменение, требуемое для отклонения клавиатуры только для редактируемого текстового поля.

Итак, я добавил к примеру Барри следующее:

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    _textBeingEdited = textField;
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
    _textBeingEdited = nil;
}

Кроме того, я изменил метод hideKeyboard следующим образом:

- (IBAction)hideKeyboard:(id)sender
{
    // Just call resignFirstResponder on all UITextFields and UITextViews in this VC
    // Why? Because it works and checking which one was last active gets messy.
    //UITextField * tf = (UITextField *) sender;
    [_textBeingEdited resignFirstResponder];
}
2
ответ дан mtorre 19 авг. '13 в 2:01
источник поделиться

Один из самых простых и кратчайших способов - добавить этот код в свой viewDidLoad

[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
                                     initWithTarget:self.view
                                     action:@selector(endEditing:)]];
2
ответ дан Sudhin Davis 07 мая '15 в 10:45
источник поделиться
- (void)viewDidLoad
{
    [super viewDidLoad]; 

UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
                                                          initWithTarget:self
                                                          action:@selector(handleSingleTap:)];
    [singleTapGestureRecognizer setNumberOfTapsRequired:1];
    [singleTapGestureRecognizer requireGestureRecognizerToFail:singleTapGestureRecognizer];

    [self.view addGestureRecognizer:singleTapGestureRecognizer];
}

- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
    [self.view endEditing:YES];
    [textField resignFirstResponder];
    [scrollView setContentOffset:CGPointMake(0, -40) animated:YES];

}
1
ответ дан Gaurav Gilani 19 мая '14 в 10:01
источник поделиться

В этом случае можно использовать ScrollView и добавить в TextField в ScrollView, и я хочу нажать ScrollView и Открыть, затем Отключить клавиатуру. Я попытался создать пример кода на всякий случай. Как это,

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.tap(_:)))
        view.addGestureRecognizer(tapGesture)
        // Do any additional setup after loading the view, typically from a nib.
    }
    func tap(gesture: UITapGestureRecognizer) {
        textField.resignFirstResponder()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Ваша раскадровка Посмотрите на это Just Like.

введите описание изображения здесь

1
ответ дан Ravi Dhorajiya 04 июня '16 в 17:16
источник поделиться

Я попробовал много ответов здесь и не повезло. Мой распознаватель жестов всегда указывал на то, что мои UIButtons не реагируют при нажатии, даже когда я устанавливаю свойство cancelsTouchesInView распознавателя жестов в значение NO.

Вот что в итоге решило проблему:

Имейте ivar:

UITapGestureRecognizer *_keyboardDismissGestureRecognizer;

Когда текстовое поле начинает редактирование, установите распознаватель жестов:

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    if(_keyboardDismissGestureRecognizer == nil)
    {
        _keyboardDismissGestureRecognizer = [[[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(dismissKeyboard)] autorelease];
        _keyboardDismissGestureRecognizer.cancelsTouchesInView = NO;

        [self.view addGestureRecognizer:_keyboardDismissGestureRecognizer];
    }
}

Тогда трюк заключается в том, как вы устанавливаете метод rejectKeyboard:

- (void) dismissKeyboard
{
    [self performSelector:@selector(dismissKeyboardSelector) withObject:nil afterDelay:0.01];
}

- (void) dismissKeyboardSelector
{
    [self.view endEditing:YES];

    [self.view removeGestureRecognizer:_keyboardDismissGestureRecognizer];
    _keyboardDismissGestureRecognizer = nil;
}

Я предполагаю, что есть только что-то о том, как выпустить выполнение executeKeyboardSelector из стека выполнения обработки касания...

1
ответ дан user1021430 15 июня '13 в 0:07
источник поделиться

Это работает

В этом примере aTextField является единственным UITextField.... Если есть другие или UITextViews, там еще немного больше.

// YourViewController.h
// ...
@interface YourViewController : UIViewController /* some subclass of UIViewController */ <UITextFieldDelegate> // <-- add this protocol
// ...
@end

// YourViewController.m

@interface YourViewController ()
@property (nonatomic, strong, readonly) UITapGestureRecognizer *singleTapRecognizer;
@end
// ...

@implementation
@synthesize singleTapRecognizer = _singleTapRecognizer;
// ...

- (void)viewDidLoad
{
    [super viewDidLoad];
    // your other init code here
    [self.view addGestureRecognizer:self.singleTapRecognizer];

{

- (UITapGestureRecognizer *)singleTapRecognizer
{
    if (nil == _singleTapRecognizer) {
        _singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapToDismissKeyboard:)];
        _singleTapRecognizer.cancelsTouchesInView = NO; // absolutely required, otherwise "tap" eats events.
    }
    return _singleTapRecognizer;
}

// Something inside this VC view was tapped (except the navbar/toolbar)
- (void)singleTapToDismissKeyboard:(UITapGestureRecognizer *)sender
{
    NSLog(@"singleTap");
    [self hideKeyboard:sender];
}

// When the "Return" key is pressed on the on-screen keyboard, hide the keyboard.
// for protocol UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
    NSLog(@"Return pressed");
    [self hideKeyboard:textField];
    return YES;
}

- (IBAction)hideKeyboard:(id)sender
{
    // Just call resignFirstResponder on all UITextFields and UITextViews in this VC
    // Why? Because it works and checking which one was last active gets messy.
    [aTextField resignFirstResponder];
    NSLog(@"keyboard hidden");
}
1
ответ дан Barry 11 июня '13 в 14:27
источник поделиться
  • Заданный делегат текстовых полей загружен:

    override func viewDidLoad() 
    {
      super.viewDidLoad()
      self.userText.delegate = self
    }
    
  • Добавьте эту функцию:

    func textFieldShouldReturn(userText: UITextField!) -> Bool 
    {
     userText.resignFirstResponder()
     return true;
    }
    
1
ответ дан seggy 06 сент. '16 в 14:06
источник поделиться

Для тех, кто борется с этим в Свифт. Это принятый ответ Jensen2k, но в Swift.

Swift 2.3

    override func viewDidLoad() {
        //.....

        let viewTapGestureRec = UITapGestureRecognizer(target: self, action: #selector(handleViewTap(_:)))
        //this line is important
        viewTapGestureRec.cancelsTouchesInView = false
        self.view.addGestureRecognizer(viewTapGestureRec)

         //.....
    }

    func handleViewTap(recognizer: UIGestureRecognizer) {
        myTextField.resignFirstResponder()
    }
1
ответ дан lwdthe1 27 окт. '16 в 21:59
источник поделиться
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first{
     view.endEditing(true)

     }
}
1
ответ дан Phani Sai 12 апр. '16 в 9:10
источник поделиться

Добавьте этот код в файл ViewController.m:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}
1
ответ дан winny the POO 17 сент. '15 в 14:35
источник поделиться

Отправлять сообщение resignFirstResponder в textfiled, который помещает его туда. Пожалуйста, см. Этот пост для получения дополнительной информации.

1
ответ дан Ke Sun 15 марта '11 в 3:34
источник поделиться

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

Что я сделал:

1) Внесите пользовательский обработчик касания в контроллер моего представления.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
    if searchBar.isFirstResponder()
    {
        // This causes the first responder, whoever it is, to resign first responder, and hide the keyboard.
        // We also "eat" the touch here and not allow it to propagate further.
        view.endEditing(true)
    }
    else
    {
        // OK to propagate the touch
        super.touchesBegan(touches, withEvent: event)
    }
}

2) Добавлен несколько методов делегатов (мои для UISearchBar, но для UITextField аналогичны). controlContainerView в коде ниже - UIView, в котором есть куча кнопок. Помните, что установка userInteractionEnabled в супервизоре отключает все его дочерние объекты.

 func searchBarTextDidBeginEditing(searchBar: UISearchBar)
 {
     controlContainerView.userInteractionEnabled = false
     someButton.userInteractionEnabled = false
 }

 func searchBarTextDidEndEditing(searchBar: UISearchBar)
 {
     searchBar.resignFirstResponder()

    // Done editing: enable the other controls again.

    controlContainerView.userInteractionEnabled = false
    someButton.userInteractionEnabled = false
}
0
ответ дан Macondo2Seattle 09 марта '16 в 7:38
источник поделиться
  • 1
  • 2

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