当用户点击其他地方时,如何从文本字段中退出第一响应者?

时间:2011-10-17 14:05:57

标签: iphone ios ios4 uiscrollview uitextfield

我用ScrollView填充了我的视图(与视图大小相同),当用户点击视图(或滚动视图)中的其他位置时,我坚持如何辞退第一响应者。有关如何做到这一点的任何想法?我正在使用以下方法,但它没有按预期工作:

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

求助,

的Stephane

18 个答案:

答案 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的所有集合。

编辑:如果它是一个可调整大小的滚动视图,请记住在按钮的视图选项中正确设置重新标注尺寸标记,这样按钮将始终展开并收缩到滚动视图的高度和宽度