Как уйти в отставку первого респондента из текстового поля, когда пользователь нажимает в другом месте? - PullRequest
24 голосов
/ 17 октября 2011

Я заполнил свой вид ScrollView (такого же размера, как и вид), и я застрял в том, как уйти в отставку первому респонденту, когда пользователь нажал в другом месте в представлении (или в виде прокрутки).Есть идеи, как это сделать?Я использую следующий метод, но он не работает должным образом:

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}

Спасибо за помощь,

Стефан

Ответы [ 17 ]

81 голосов
/ 24 августа 2012

Я нашел ответ здесь: ссылка

Если вашей конечной целью является просто отставка первого респондента, это должно сработать: [self.view endEditing: YES]

Этот метод предназначен именно для этого!Ссылка: endEditing:

Заставляет представление (или одно из его встроенных текстовых полей) отказаться от статуса первого респондента.

18 голосов
/ 13 августа 2013

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

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

На ваш взгляд загрузил:

UITapGestureRecognizer* tapBackground = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard:)];
[tapBackground setNumberOfTapsRequired:1];
[self.view addGestureRecognizer:tapBackground];

.. и определите целевое действие, которое должно быть запущено при нажатии:

-(void) dismissKeyboard:(id)sender
{
    [self.view endEditing:YES];
}
10 голосов
/ 17 января 2017

Для Swift 3 и Swift 4 Вы можете сделать это:

func viewDidLoad() {
    super.viewDidLoad()

    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.hideKeyboardByTappingOutside))

    self.view.addGestureRecognizer(tap)
}

@objc func hideKeyboardByTappingOutside() {
    self.view.endEditing(true)
}
9 голосов
/ 12 апреля 2013

Лучший вариант - самый короткий путь;)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}
4 голосов
/ 17 октября 2011

UIViewController наследуется от UIResponder, поэтому наивным способом (я уверен, что это не самый умный способ сделать это) было бы переписать следующие методы (как минимум 1 из них)

– touchesBegan:withEvent:
– touchesMoved:withEvent:
– touchesEnded:withEvent:
- touchesCancelled:withEvent:

Далее вы можете получить потроганный вид, выполнив

UITouch *touch = [touches anyObject];
UIView *touchedView = [touch view];

наконец, подать в отставку первого респондента, если это представление не ваше текстовое поле

if(touchedView != textField){
    [textField resignFirstResponder];
}

_

Недостатки этого подхода:

Вам придется самостоятельно справиться с «краном». (Та же проблема, что и у старой iOS 3.1 или более ранней). Вам придется придумать свою собственную реализацию, чтобы отличить отдельные касания от перетаскивания, пролистывания, двойного касания, длинных касаний и т. Д. Не сложно заставить его работать хорошо, но вряд ли вы получите его точно так же, как Apple обнаруживает касания (время, расстояния, пороги считаются!) Однако это зависит от ваших потребностей.

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

Надеюсь, это поможет

3 голосов
/ 27 мая 2015

Никто еще не представил лучший ответ здесь:

[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];

Из документации по этому методу:

Обычно этот метод вызывается объектом UIControl, который пользователькоснулся. Реализация по умолчанию отправляет метод действия указанному целевому объекту или, если цель не указана, первому респонденту .Подклассы могут переопределять этот метод для выполнения специальной отправки сообщений действий.

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

3 голосов
/ 26 мая 2015
    -(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [self.TextField resignFirstResponder];

    return YES;
}
2 голосов
/ 17 октября 2011

Присвойте уникальный тег вашему UITextfield (то есть 333), затем, чтобы уйти в отставку первый респондент, сделайте это:

UITextField *textField = (UITextField *)[self.view viewWithTag:333];
[textField resignFirstResponder];
1 голос
/ 17 октября 2011

Просто создайте IBOutlet или указатель на текстовое поле и вызывайте [textField resignFirstResponder]; из любого места.

1 голос
/ 26 мая 2015
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(TapTodissmiss)];

[self.view addGestureRecognizer:tap];

и селектор

-(void)TapTodissmiss{

    [self.txtffld resignFirstResponder];

}
...