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

ios cocoa-touch uitextfield uikit

238305 просмотра

30 ответа

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

Автор: jonepatr Источник Размещён: 12.11.2019 09:08

Ответы (30)


745 плюса

Решение

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

Код:

В viewDidLoad

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

[self.view addGestureRecognizer:tap];

В dismissKeyboard:

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

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

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

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

Для dismissKeyboard

func dismissKeyboard (_ sender: UITapGestureRecognizer) {
    aTextField.resignFirstResponder()
}
Автор: Jensen2k Размещён: 15.03.2011 12:36

173 плюса

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

Используйте ивар, который инициализируется во время 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];
}
Автор: drewish Размещён: 24.07.2012 03:01

102 плюса

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

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

Или же

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

https://github.com/michaeltyson/TPKeyboardAvoiding

Автор: Prasad De Zoysa Размещён: 20.06.2012 10:52

87 плюса

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

[tap setCancelsTouchesInView:NO];

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

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

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

Автор: Qiao Yi Размещён: 03.02.2012 05:21

55 плюса

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

- (IBAction)dismissKeyboard:(id)sender {
    [aTextBox resignFirstResponder];
}
Автор: Dmitry Sitnikov Размещён: 04.08.2011 08:43

28 плюса

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

override func viewDidLoad() {
    super.viewDidLoad()

    let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
    tapper.cancelsTouchesInView = false
    view.addGestureRecognizer(tapper)
}
Автор: Rob Размещён: 06.01.2015 03:05

24 плюса

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
    }
}
Автор: FBente Размещён: 26.01.2018 01:09

17 плюса

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

- (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];
            }
        } 
    }
}
Автор: Mr H Размещён: 04.10.2011 05:42

14 плюса

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

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: https://stackoverflow.com/a/18756253/417652

Автор: eduludi Размещён: 10.10.2014 10:16

10 плюса

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

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

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

Автор: Enzo Tran Размещён: 05.01.2012 04:10

10 плюса

Swift 4 oneliner

view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))
Автор: newDeveloper Размещён: 01.07.2018 03:13

7 плюса

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

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

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

Автор: KoreanXcodeWorker Размещён: 11.03.2016 05:56

6 плюса

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


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

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

@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>

- (IBAction)dissmissKeyboardOnTap:(id)sender;

@end

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

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

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

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


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

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

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

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

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

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

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

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

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

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

Автор: Chris Halcrow Размещён: 16.10.2015 01:47

5 плюса

Если я вас правильно понял, вы хотите подать в отставку, нажав на кнопку вне, textfieldно у вас нет ссылки на нее 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;
    }
    
Автор: rptwsthi Размещён: 01.03.2013 02:51

5 плюса

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

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

Первый из них будет анимировать экранную клавиатуру при прокрутке таблицы, а второй - скрыть клавиатуру, как приложение «Сообщения».

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

Автор: Joe Masilotti Размещён: 14.08.2014 01:05

3 плюса

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

viewDidLoad:

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

В любом месте:

-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
    [textFieldName resignFirstResponder];
    puts("Dismissed the keyboard");
}
Автор: John Riselvato Размещён: 17.07.2012 12:50

3 плюса

Здесь вы найдете множество отличных ответов об использовании кнопки UITapGestureRecognizer--all of break UITextField(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);
}

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

Автор: skedastik Размещён: 22.11.2013 03:59

3 плюса

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

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

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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.window endEditing:true];
    [super touchesBegan:touches withEvent:event];
}
@end
Автор: Hiren Размещён: 29.10.2015 09:12

3 плюса

Быстрая версия ответа @ 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:"))
Автор: Syed Asad Ali Размещён: 22.04.2016 10:16

2 плюса

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

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

- (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];
}
Автор: mtorre Размещён: 18.08.2013 11:01

2 плюса

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

[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
                                     initWithTarget:self.view
                                     action:@selector(endEditing:)]];
Автор: Sudhin Davis Размещён: 07.05.2015 07:45

2 плюса

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

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

     }
}
Автор: Phani Sai Размещён: 12.04.2016 06:10

2 плюса

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

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

Ивару:

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выполнение из стека выполнения обработки касанием ...

Автор: user1021430 Размещён: 14.06.2013 09:07

1 плюс

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

Автор: Ke Sun Размещён: 15.03.2011 12:34

1 плюс

Это работает

В этом примере 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's 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");
}
Автор: user246672 Размещён: 11.06.2013 11:27

1 плюс

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

}
Автор: Gaurav Gilani Размещён: 19.05.2014 07:01

1 плюс

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

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}
Автор: aashish tamsya Размещён: 17.09.2015 11:35

1 плюс

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

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

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

Автор: Ravi Dhorajiya Размещён: 04.06.2016 02:16

1 плюс

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

Автор: Nirzar Gandhi Размещён: 25.09.2015 01:37

1 плюс

  • Установить текстовые поля делегата в представлении загрузил:

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

    func textFieldShouldReturn(userText: UITextField!) -> Bool 
    {
     userText.resignFirstResponder()
     return true;
    }
    
Автор: seggy Размещён: 06.09.2016 11:06
Вопросы из категории :
32x32