我用ScrollView填充了我的视图(与视图大小相同),当用户点击视图(或滚动视图)中的其他位置时,我坚持如何辞退第一响应者。有关如何做到这一点的任何想法?我正在使用以下方法,但它没有按预期工作:
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
求助,
的Stephane
答案 0 :(得分:80)
我在这里找到了答案:link
如果你的最终目的只是让第一响应者辞职,那么 应该工作:[self.view endEditing:YES]
此方法适合它! 参考:endEditing:
使视图(或其中一个嵌入的文本字段)重新签署第一个响应者状态。
答案 1 :(得分:18)
要获得更强大,更干净的解决方案,请在主视图中添加点按手势识别器。
这对于嵌套视图效果更好,并且比代码和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];
}
答案 2 :(得分:10)
对于 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)
}
答案 3 :(得分:9)
最好的选择是最短的方式;)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
答案 4 :(得分:4)
UIViewController
继承自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检测水龙头(时间,距离,门槛数!) 但是,这取决于您的需求。
如果您的视图结构足够简单,那么您可以在容器视图中添加手势识别器,并在每次调用处理程序时重新启动第一个响应者:)
希望这有帮助
答案 5 :(得分:3)
目前还没有人提出最佳答案:
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
从此方法的文档:
通常,此方法由用户的UIControl对象调用 感动了。 默认实现调度操作方法 到给定的目标对象,或者,如果没有指定目标,则为第一个 应答即可。子类可以重写此方法以执行特殊操作 发送行动信息。
我加粗了该段的相关部分。通过为nil
参数指定to:
,我们会自动调用第一个响应者上的给定选择器,无论它在哪里,我们都不需要了解视图层次结构中的位置是。这也可用于在第一响应者上调用其他方法,而不仅仅是使其重新响应第一响应者状态。
答案 6 :(得分:3)
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self.TextField resignFirstResponder];
return YES;
}
答案 7 :(得分:2)
为您的UITextfield(即333)提供一个唯一标记,然后让第一个响应者辞职:
UITextField *textField = (UITextField *)[self.view viewWithTag:333];
[textField resignFirstResponder];
答案 8 :(得分:1)
我将其作为单独的答案发布,因为许多其他答案建议使用[textField resignFirstResponder]
。这导致Xcode 11.5中出现无效的功能错误,并且添加了"Unable to insert COPY_SEND"
在装有iOS 9.3.6的iPad上:
2020-05-23 20:35:01.576 _BSMachError: (os/kern) invalid capability (20)
2020-05-23 20:35:01.580 _BSMachError: (os/kern) invalid name (15)
在装有iPadOS 13.5的iPad上:
2020-05-23 20:38:49 [Common] _BSMachError: port 12f0f; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
在装有iOS 13.5的iPhone上:
2020-05-23 20:43:34 [Common] _BSMachError: port d503; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
[textField resignFirstResponder]
无法再使用。
答案 9 :(得分:1)
只需创建IBOutlet
或指向文字字段的指针,然后从您想要的地方拨打[textField resignFirstResponder];
。
答案 10 :(得分:1)
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(TapTodissmiss)];
[self.view addGestureRecognizer:tap];
和选择器
-(void)TapTodissmiss{
[self.txtffld resignFirstResponder];
}
答案 11 :(得分:0)
这就是我做的......
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];
}
答案 12 :(得分:0)
对于我的实现,[self.view endEditing:YES]不起作用。
为了最终确保键盘被隐藏,我必须将我的一个视图作为第一个响应者,然后立即按照以下功能使其辞职:
-(void) hideKeyboardPlease{
[uiTextTo becomeFirstResponder];
[uiTextTo resignFirstResponder];
}
答案 13 :(得分:0)
在ViewController.h文件中创建您的IBOutlet,如下所示:
//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
答案 14 :(得分:0)
这是iv发现的最简单的方法。只需在视图上添加一个水龙头手势识别器,就可以了。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
答案 15 :(得分:0)
<强>更新强>
我找到了另一种简单的方法
只需声明一个属性: -
@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];
实施文本字段委托方法didBeginEditing
-(void)textFieldDidBeginEditing:(UITextField *)textField{
_currentTextfield=textField;
}
实施点击手势方法(_resignTextField)
-(void)tapMethod:(UITapGestureRecognizer *)Gesture{
[_currentTextfield resignFirstResponder];
}
答案 16 :(得分:0)
如果可能,最好的选择是让 UIView 继承 UIButton 。
您只需要在Interface Builder中进行更改即可立即获得创建动作“Touch Up Inside”的选项,就像任何其他按钮一样。
您的视图将照常运行,因为UIButton仍然是一个视图,但当有人点击视图时您会收到通知。你可以在那里打电话
[self.view endEditing:YES];
重新签名任何键盘。
请注意,如果您的观点是UIScrollView,则此解决方案不适合您。
答案 17 :(得分:-5)
在它后面创建一个大按钮,按钮的回调调用resignFirstResponder
到你拥有的每个输入。只需确保将用户与之交互的所有内容放在按钮顶部。
当然按钮将是自定义矩形和透明的。
我将研究实现一个名为resignables的IBOutletCollection,并将每个输入设置为该集合。按钮回调遍历调用resignFirstResponder
的所有集合。
编辑:如果它是一个可调整大小的滚动视图,请记住在按钮的视图选项中正确设置重新标注尺寸标记,这样按钮将始终展开并收缩到滚动视图的高度和宽度