it-swarm.com.ru

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

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

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

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

Stephane

24
Steve

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

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

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

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

79
DanSkeel

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

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

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

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

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

-(void) dismissKeyboard:(id)sender
{
    [self.view endEditing:YES];
}
18
Andres Canella

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

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

Для 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)
}
8
pableiros

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 обнаруживает касания (время, расстояния, пороги считаются!) Однако это зависит от ваших потребностей.

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

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

4
nacho4d

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

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

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

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

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

3
Gavin
    -(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [self.TextField resignFirstResponder];

    return YES;
}
3
Deepakraj Murugesan

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

UITextField *textField = (UITextField *)[self.view viewWithTag:333];
[textField resignFirstResponder];
2
Lefteris
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(TapTodissmiss)];

[self.view addGestureRecognizer:tap];

и селектор

-(void)TapTodissmiss{

    [self.txtffld resignFirstResponder];

}
1
Ghanshyam Tomar

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

1
Or Ron

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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

[self.view endEditing:YES];

}

0
Andrew Cook

Для моей реализации [self.view endEditing: YES] не сработало. 

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

-(void) hideKeyboardPlease{
   [uiTextTo becomeFirstResponder];
   [uiTextTo resignFirstResponder];
}
0
Lenny

Когда это возможно, лучше всего сделать так, чтобы ваш UIView наследовал от UIButton

Вам просто нужно изменить его в Интерфейсном Разработчике, и сразу же вы получите возможность создать Действие «Подправить внутри», как и любую другую кнопку. 

Ваше представление будет работать как обычно, потому что UIButton все еще является представлением, но вы будете получать уведомления, когда кто-то нажимает на представление. Туда можно позвонить 

[self.view endEditing:YES];

В отставку любую клавиатуру.

Обратите внимание, что если ваш взгляд UIScrollView это решение не для вас.

0
Julio Bailon

Обновление

Я нашел другой простой способ 

просто объявите свойство: -

@property( strong , nonatomic) UITextfield *currentTextfield;

и Gecognizer Жест касания: -

@property (strong , nonatomic) UITapGestureRecognizer *resignTextField;

В ViewDidLoad

_currentTextfield=[[UITextField alloc]init];
_resignTextField=[[UITapGestureRecognizer alloc]initWithTarget:@selector(tapMethod:)];

[self.view addGestureRecognizer:_resignTextField];

Реализовать метод делегата текстового поля didBeginEditing

 -(void)textFieldDidBeginEditing:(UITextField *)textField{


      _currentTextfield=textField;

    }

Реализуйте метод жестов касания (_resignTextField)

 -(void)tapMethod:(UITapGestureRecognizer *)Gesture{

     [_currentTextfield resignFirstResponder];

 }
0
dreamBegin

Создайте свой IBOutlet в файле ViewController.h, как показано ниже:

//YOUR ViewController.h FILE

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    //WIRE THIS WITH YOUR UITextField OBJECT AT YOUR .xib FILE
    IBOutlet UITextField *yourIBOutletUITextField;
}

@end

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

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

как ниже:

//YOUR ViewController.m FILE

#import "ViewController.h"

@implementation ViewController


//ADD THIS METHOD BELOW
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
     [yourIBOutletUITextField resignFirstResponder];
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    }

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end
0
EFE

Вот что я делаю...

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideAllKeyboards)];
tapGesture.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapGesture];

-(void) hideAllKeyboards {
    [textField_1 resignFirstResponder];
    [textField_2 resignFirstResponder];
    [textField_3 resignFirstResponder];
    .
    .
    .
    [textField_N resignFirstResponder];
}
0
Fahim Parkar