当用户点击其他地方时,如何从文本字段中辞退第一响应者?
我用ScrollView填充了我的视图(与视图大小相同),当用户点击View(或scrollview)中的其他位置时,我仍然坚持如何辞退第一响应者。 有关如何做到这一点的任何想法? 我正在使用以下方法,但它没有按预期工作:
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { [textField resignFirstResponder]; return YES; }
感谢帮助,
斯特凡
我在这里找到了答案: 链接
如果你的最终目的只是让第一响应者辞职,这应该有效:[self.view endEditing:YES]
这种方法适合它! 参考: endEditing:
导致视图(或其中一个嵌入的文本字段)重新签署第一个响应者状态。
要获得更强大,更干净的解决方案,请在主视图中添加点击手势识别器。
这对于嵌套视图更有效,并且比代码和UI构建器中的秘密按钮更清晰。
在您的视图中加载:
UITapGestureRecognizer* tapBackground = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard:)]; [tapBackground setNumberOfTapsRequired:1]; [self.view addGestureRecognizer:tapBackground];
..并定义要在点击时触发的目标操作:
-(void) dismissKeyboard:(id)sender { [self.view endEditing:YES]; }
最好的选择是最短的方式;)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.view endEditing:YES]; }
对于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) }
UIViewController
inheritance自UIResponder
所以一种天真的方式(我很确定不是最聪明的方法)将覆盖以下方法(至少其中一个)
– 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检测水龙头(时间,距离,阈值计数!)但是,这取决于您的需求。
如果您的视图结构足够简单,那么您可以向容器视图添加手势识别器,并在每次调用处理程序时重新调整第一个响应者:)
希望这可以帮助
-(BOOL)textFieldShouldReturn:(UITextField *)textField { [self.TextField resignFirstResponder]; return YES; }
目前还没有人提出最佳答案:
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
从这个方法的文档:
通常,此方法由用户触摸的UIControl对象调用。 默认实现将action方法分派给给定的目标对象,如果没有指定目标,则分配给第一个响应者 。 子类可以重写此方法以执行操作消息的特殊分派。
我加粗了该段的相关部分。 通过为to:
参数指定nil
,我们自动在第一个响应者上调用给定的选择器,无论它在哪里,我们不需要知道它在视图层次结构中的位置。 这也可以用于在第一响应者上调用其他方法,而不仅仅是使其重新响应第一响应者状态。
给你的UITextfield(即333)一个唯一的标签,然后让第一个响应者辞职:
UITextField *textField = (UITextField *)[self.view viewWithTag:333]; [textField resignFirstResponder];
只需创建一个IBOutlet
或指向文本字段的指针,然后调用[textField resignFirstResponder];
从哪里你想要的。
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(TapTodissmiss)]; [self.view addGestureRecognizer:tap];
和选择器
-(void)TapTodissmiss{ [self.txtffld resignFirstResponder]; }
如果可能,最好的选择是让你的UIViewinheritanceUIButton 。
您只需在Interface Builder中进行更改即可立即获得创建动作“Touch Up Inside”的选项,就像任何其他按钮一样。
您的视图将照常工作,因为UIButton仍然是一个视图,但当有人点击视图时您会收到通知。 你可以打电话
[self.view endEditing:YES];
辞去任何键盘。
请注意,如果您的视图是UIScrollView,则此解决方案不适合您。
在ViewController.h文件中创建您的IBOutlet,如下所示:
//YOUR ViewController.h FILE #import @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. // eg 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
对于我的实现,[self.view endEditing:YES]不起作用。
为了最终确保键盘被隐藏,我必须将我的一个视图作为第一个响应者,然后立即按照以下function使其辞职:
-(void) hideKeyboardPlease{ [uiTextTo becomeFirstResponder]; [uiTextTo resignFirstResponder]; }
这就是我做的……
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]; }
这是iv发现的最简单的方法。 只需在视图上添加一个点击手势识别器,就可以了。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.view endEditing:YES];
}
更新
我发现了另一个简单的方法
只需声明一个属性: –
@property( strong , nonatomic) UITextfield *currentTextfield;
和一个Tap Gesture Gecognizer: –
@property (strong , nonatomic) UITapGestureRecognizer *resignTextField;
在ViewDidLoad中
_currentTextfield=[[UITextField alloc]init]; _resignTextField=[[UITapGestureRecognizer alloc]initWithTarget:@selector(tapMethod:)]; [self.view addGestureRecognizer:_resignTextField];
实现textfield委托方法didBeginEditing
-(void)textFieldDidBeginEditing:(UITextField *)textField{ _currentTextfield=textField; }
实现您的Tap手势方法(_resignTextField)
-(void)tapMethod:(UITapGestureRecognizer *)Gesture{ [_currentTextfield resignFirstResponder]; }
在它后面创建一个大按钮,按钮的回调将resignFirstResponder
调用到您拥有的每个输入。 只需确保将用户与之交互的所有内容放在按钮顶部。
当然按钮将是自定义矩形和透明的。
我将研究实现一个名为resignables的IBOutletCollection并将每个输入设置为该集合。 按钮回调遍历该集合,将resignFirstResponder
调用给所有人。
编辑:如果它是一个可resize的滚动视图,请记住在按钮的视图选项中正确设置重新标注尺寸标记,这样按钮将始终展开并收缩到滚动视图的高度和宽度