iOS - Отключить клавиатуру при касании за пределами UITextField

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

Ответ 1

Вам нужно добавить 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()
}

Ответ 2

Я растянул несколько ответов.

Используйте 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];
}

Ответ 3

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

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

или

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

https://github.com/michaeltyson/TPKeyboardAvoiding

Ответ 4

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

[tap setCancelsTouchesInView:NO];

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

Прочитайте об этом property здесь (ищите CancelsTouchesInView): описание класса UIGestureRecognizer

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

Ответ 5

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

- (IBAction)dismissKeyboard:(id)sender {
    [aTextBox resignFirstResponder];
}

Ответ 6

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

override func viewDidLoad() {
    super.viewDidLoad()

    let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
    tapper.cancelsTouchesInView = false
    view.addGestureRecognizer(tapper)
}

Ответ 7

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

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

Ответ 8

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

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: fooobar.com/questions/17499/...

Ответ 9

Swift 4

Настройте свой UIViewController с помощью этого метода расширения, например, в viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
    self.setupHideKeyboardOnTap()
}

и клавиатура будет отклонена, даже нажав на панель NavigationBar.

import UIKit
extension UIViewController {
    /// Call this once to dismiss open keyboards by tapping anywhere in the view controller
    func setupHideKeyboardOnTap() {
        self.view.addGestureRecognizer(self.endEditingRecognizer())
        self.navigationController?.navigationBar.addGestureRecognizer(self.endEditingRecognizer())
    }

    /// Dismisses the keyboard from self.view
    private func endEditingRecognizer() -> UIGestureRecognizer {
        let tap = UITapGestureRecognizer(target: self.view, action: #selector(self.view.endEditing(_:)))
        tap.cancelsTouchesInView = false
        return tap
    }
}

Ответ 10

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

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

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

Ответ 11

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


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

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

@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>

- (IBAction)dissmissKeyboardOnTap:(id)sender;

@end

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

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

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

enter image description here


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

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

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

enter image description here

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

enter image description here

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

enter image description here

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

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

Ответ 13

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

Ответ 14

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

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

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

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

Ответ 15

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

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");
}

Ответ 16

Здесь много замечательных ответов об использовании 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);
}

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

Ответ 17

Вы можете создать категорию для 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

Ответ 18

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

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

func dismissKeyboard() {
    aTextField.resignFirstResponder()
}

Один лайнер

self.view.addTapGesture(UITapGestureRecognizer.init(target: self, action: "endEditing:"))

Ответ 19

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

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

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

Ответ 20

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

[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
                                     initWithTarget:self.view
                                     action:@selector(endEditing:)]];

Ответ 21

Swift 4 oneliner

view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))

Ответ 22

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

Ответ 23

Это работает

В этом примере 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");
}

Ответ 24

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

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

Ивару:

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

Тогда дело в том, как настроить метод dismissKeyboard:

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

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

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

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

Ответ 25

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

}

Ответ 26

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

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

Ответ 27

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

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

    [self.view addGestureRecognizer:tap];


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

}

Ответ 28

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

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

     }
}

Ответ 29

В этом случае можно использовать 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.

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

Ответ 30

  • Заданный делегат текстовых полей загружен:

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

    func textFieldShouldReturn(userText: UITextField!) -> Bool 
    {
     userText.resignFirstResponder()
     return true;
    }