382

我的表格中的许多表格单元格中散布着很多控件,我想知道是否有一种更简单的方法可以关闭键盘,而不必遍历我的所有控件并将它们全部作为第一响应者。我想问题是..我如何让当前的第一响应者使用键盘?

4

31 回答 31

805

尝试:

[self.view endEditing:YES];
于 2010-09-14T01:13:30.577 回答
126

您可以使用 强制当前正在编辑的视图退出其第一响应者状态[view endEditing:YES]。这隐藏了键盘。

与, 不同-[UIResponder resignFirstResponder]-[UIView endEditing:]将搜索子视图以找到当前的第一响应者。因此,您可以将它发送到您的顶级视图(例如self.view在 a 中UIViewController),它会做正确的事情。

(这个答案以前包括其他几个解决方案,它们也有效,但比必要的更复杂。我已经删除了它们以避免混淆。)

于 2009-04-12T05:39:09.003 回答
94

您可以向应用程序发送一个 nil 目标操作,它会随时退出第一响应者,而不必担心当前哪个视图具有第一响应者状态。

目标-C:

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

斯威夫特 3.0:

UIApplication.shared.sendAction(#selector(resignFirstResponder), to: nil, from: nil, for: nil)

Nil 目标操作在 Mac OS X 上对于菜单命令很常见,这里是它们在 iOS 上的用途。

于 2013-01-05T01:32:58.677 回答
56

老实说,我对这里提出的任何解决方案都不感兴趣。我确实找到了一种使用 TapGestureRecognizer 的好方法,我认为它可以解决您的问题的核心:当您单击键盘以外的任何东西时,关闭键盘。

  1. 在 viewDidLoad 中,注册接收键盘通知并创建一个 UITapGestureRecognizer:

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    
    [nc addObserver:self selector:@selector(keyboardWillShow:) name:
    UIKeyboardWillShowNotification object:nil];
    
    [nc addObserver:self selector:@selector(keyboardWillHide:) name:
    UIKeyboardWillHideNotification object:nil];
    
    tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
    action:@selector(didTapAnywhere:)];
    
  2. 添加键盘显示/隐藏响应器。在那里,您将 TapGestureRecognizer 添加和删除到 UIView 中,当被点击时应该关闭键盘。注意:您不必将其添加到所有子视图或控件中。

    -(void) keyboardWillShow:(NSNotification *) note {
        [self.view addGestureRecognizer:tapRecognizer];
    }
    
    -(void) keyboardWillHide:(NSNotification *) note
    {
        [self.view removeGestureRecognizer:tapRecognizer];
    }
    
  3. TapGestureRecognizer 将在点击时调用您的函数,您可以像这样关闭键盘:

    -(void)didTapAnywhere: (UITapGestureRecognizer*) recognizer {    
        [textField resignFirstResponder];
    }
    

这个解决方案的好处是它只过滤 Taps,而不是滑动。因此,如果您在键盘上方有滚动内容,则滑动仍会滚动并显示键盘。通过在键盘消失后移除手势识别器,未来对视图的点击会得到正常处理。

于 2011-06-27T22:00:56.400 回答
24

这是一种解决方案,通过在一个地方添加代码(因此不必为每个文本字段添加处理程序),return任何文本字段中敲击键盘时都会消失:


考虑这种情况:

我有viewcontroller两个文本字段(用户名和密码)。和viewcontroller实现UITextFieldDelegate协议

我在 viewDidLoad 中这样做

- (void)viewDidLoad 
{
    [super viewDidLoad];

    username.delegate = self;
    password.delegate = self;
}

并且视图控制器将可选方法实现为

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

并且无论您在哪个文本字段中,只要我敲击return键盘,它就会被解雇!

在您的情况下,只要您将所有文本字段的委托设置为 self 并实现textFieldShouldReturn

于 2009-06-24T08:42:47.797 回答
14

更好的方法是让某些东西“窃取”第一响应者的身份。

由于 UIApplication 是 UIResponder 的子类,您可以尝试:

[[UIApplication sharedApplication] becomeFirstResponder]
[[UIApplication sharedApplication] resignFirstResponder]

如果做不到这一点,请创建一个具有零大小框架的新 UITextField,将其添加到某处的视图中并执行类似的操作(然后是辞职)。

于 2009-04-13T06:36:50.153 回答
8

把它藏在一些实用程序类中。

+ (void)dismissKeyboard {
    [self globalResignFirstResponder];
}

+ (void) globalResignFirstResponder {
    UIWindow * window = [[UIApplication sharedApplication] keyWindow];
    for (UIView * view in [window subviews]){
        [self globalResignFirstResponderRec:view];
    }
}

+ (void) globalResignFirstResponderRec:(UIView*) view {
    if ([view respondsToSelector:@selector(resignFirstResponder)]){
        [view resignFirstResponder];
    }
    for (UIView * subview in [view subviews]){
        [self globalResignFirstResponderRec:subview];
    }
}
于 2011-06-24T17:27:57.147 回答
6

@Nicholas Riley & @Kendall Helmstetter Geln & @cannyboy:

绝对精彩!

谢谢你。

考虑到您的建议和此线程中其他人的建议,这就是我所做的:

使用时的样子:

[[self appDelegate] dismissKeyboard]; (注意:我添加了 appDelegate 作为 NSObject 的补充,所以我可以在任何地方使用任何东西)

它在引擎盖下的样子:

- (void)dismissKeyboard 
{
    UITextField *tempTextField = [[[UITextField alloc] initWithFrame:CGRectZero] autorelease];
    tempTextField.enabled = NO;
    [myRootViewController.view addSubview:tempTextField];
    [tempTextField becomeFirstResponder];
    [tempTextField resignFirstResponder];
    [tempTextField removeFromSuperview];
}

编辑

修改我对包括的答案tempTextField.enabled = NO;。如果您在整个应用程序中依赖这些通知,禁用文本字段将阻止UIKeyboardWillShowNotification发送键盘通知。UIKeyboardWillHideNotification

于 2010-09-14T17:07:57.177 回答
5

当用户触摸 UITextField 或键盘之外的屏幕上的任何位置时如何在 iOS 中关闭键盘的快速提示。考虑到 iOS 键盘可以占用多少空间,为用户提供一种简单直观的方式来关闭键盘是很有意义的。

这是一个链接

于 2011-09-17T15:44:04.930 回答
5

这里有很多过于复杂的答案,可能是因为这在 iOS 文档中不容易找到。JosephH 就在上面:

[[view window] endEditing:YES];
于 2012-03-29T21:28:31.983 回答
5

这是我在代码中使用的内容。它就像一个魅力!

在 yourviewcontroller.h 添加:

@property (nonatomic) UITapGestureRecognizer *tapRecognizer;

现在在 .m 文件中,将其添加到您的 ViewDidLoad 函数中:

- (void)viewDidLoad {
    //Keyboard stuff
    tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapAnywhere:)];
    tapRecognizer.cancelsTouchesInView = NO;
    [self.view addGestureRecognizer:tapRecognizer];
}

此外,在 .m 文件中添加此函数:

- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
    [self.view endEditing:YES];
}
于 2015-01-07T19:55:26.457 回答
4

甚至比 Meagar 的答案更简单

覆盖touchesBegan:withEvent:

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

dismiss the keyboard您触摸background.

于 2013-12-04T14:57:45.267 回答
3

您应该发送endEditing:到工作窗口作为子类UIView

[[UIApplication sharedApplication].windows.firstObject endEditing:NO];
于 2015-09-17T20:19:26.870 回答
2

在视图控制器的头文件中添加<UITextFieldDelegate>控制器接口的定义,使其符合 UITextField 委托协议...

@interface someViewController : UIViewController <UITextFieldDelegate>

...在控制器的实现文件 (.m) 中添加以下方法,或者如果您已经有 viewDidLoad 方法,则添加其中的代码...

- (void)viewDidLoad
{
    // Do any additional setup after loading the view, typically from a nib.
    self.yourTextBox.delegate = self;
}

...然后,将 yourTextBox 链接到您的实际文本字段

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField 
{
    if (theTextField == yourTextBox) {
        [theTextField resignFirstResponder];
    }
    return YES;
}
于 2012-04-21T23:08:10.637 回答
2

从 UITableView 和 UIScrollView 关闭键盘的最佳方法是:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
于 2016-08-09T08:16:22.290 回答
2

在 swift 3 中,您可以执行以下操作

UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
于 2017-02-20T19:18:54.113 回答
1

杰里米的回答对我来说不太有效,我想是因为我在选项卡视图中有一个导航堆栈,上面有一个模式对话框。我现在正在使用以下内容,它对我有用,但您的里程可能会有所不同。

 // dismiss keyboard (mostly macro)
[[UIApplication sharedApplication].delegate dismissKeyboard]; // call this in your to app dismiss the keybaord

// --- dismiss keyboard (in indexAppDelegate.h) (mostly macro)
- (void)dismissKeyboard;

// --- dismiss keyboard (in indexAppDelegate.m) (mostly macro)
// do this from anywhere to dismiss the keybard
- (void)dismissKeyboard {    // from: http://stackoverflow.com/questions/741185/easy-way-to-dismiss-keyboard

    UITextField *tempTextField = [[UITextField alloc] initWithFrame:CGRectZero];

    UIViewController *myRootViewController = <#viewController#>; // for simple apps (INPUT: viewController is whatever your root controller is called.  Probably is a way to determine this progragrammatically)
    UIViewController *uivc;
    if (myRootViewController.navigationController != nil) { // for when there is a nav stack
        uivc = myRootViewController.navigationController;
    } else {
        uivc = myRootViewController;
    }

    if (uivc.modalViewController != nil) { // for when there is something modal
        uivc = uivc.modalViewController;
    } 

    [uivc.view  addSubview:tempTextField];

    [tempTextField becomeFirstResponder];
    [tempTextField resignFirstResponder];
    [tempTextField removeFromSuperview];
    [tempTextField release];

}
于 2010-11-23T18:45:50.283 回答
1

在某些情况下,您可能还需要覆盖 UIViewController disablesAutomaticKeyboardDismissal 以使其正常工作。如果您有 UINavigationController,这可能必须在其上完成。

于 2012-07-16T12:55:15.770 回答
1

子类化您的文本字段...以及文本视图

在子类中放置此代码..

-(void)conformsToKeyboardDismissNotification{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissKeyBoard) name:KEYBOARD_DISMISS object:nil];
}

-(void)deConformsToKeyboardDismissNotification{

    [[NSNotificationCenter defaultCenter] removeObserver:self name:KEYBOARD_DISMISS object:nil];
}

- (void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self resignFirstResponder];
}

在文本字段代表中(类似于 textview 代表)

-(void)textFieldDidBeginEditing:(JCPTextField *)textField{
     [textField conformsToKeyboardDismissNotification];
}


- (void)textFieldDidEndEditing:(JCPTextField *)textField{
    [textField deConformsToKeyboardDismissNotification];
}

一切就绪.. 现在只需在代码中的任何位置发布通知。它将放弃任何键盘。

于 2013-10-11T14:53:06.827 回答
1

我们可以迅速做到

UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)
于 2015-03-31T08:16:43.943 回答
1

要在键盘弹出后关闭键盘,有两种情况

  1. 当 UITextField在 UIScrollView 内时

  2. 当 UITextField在 UIScrollView 之外时

2.当 UITextField 在 UIScrollView 之外时,覆盖 UIViewController 子类中的方法

您还必须为所有 UITextView 添加委托

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
}
  1. 滚动视图中,Tapping outside 不会触发任何事件,因此在这种情况下,请使用 Tap Gesture Recognizer,拖放滚动视图的UITapGesture并为其创建 IBAction

要创建 IBAction,请按 ctrl+ 单击 UITapGesture 并将其拖到 viewcontroller 的 .h 文件中。

在这里,我将 tappedEvent 命名为我的操作名称

- (IBAction)tappedEvent:(id)sender {
      [self.view endEditing:YES];  }

以上给出的信息来源于以下链接,如果您不理解以上数据,请参考更多信息或与我联系。

http://samwize.com/2014/03/27/dismiss-keyboard-when-tap-outside-a-uitextfield-slash-uitextview/

于 2015-12-02T05:32:11.860 回答
0

我讨厌在不使用私有 API 调用的情况下以编程方式关闭键盘的“全局”方式。通常,我需要在不知道第一响应者是什么对象的情况下以编程方式关闭键盘。我已经self使用 Objective-C 运行时 API 进行检查,枚举其所有属性,提取那些 type 的属性,UITextField并向它们发送resignFirstResponder消息。

做这件事应该不难……

于 2009-11-30T15:49:47.680 回答
0

这并不漂亮,但是当我不知道响应者是什么时,我辞去 firstResponder 的方式:

在 IB 中或以编程方式创建 UITextField。使其隐藏。如果您在 IB 中制作,请将其链接到您的代码。然后,当您想关闭键盘时,将响应者切换到不可见的文本字段,并立即将其退出:

  [self.invisibleField becomeFirstResponder];
  [self.invisibleField resignFirstResponder];
于 2010-05-24T18:34:26.053 回答
0

您可以递归地遍历子视图,存储所有 UITextField 的数组,然后循环遍历它们并全部退出。

不是一个很好的解决方案,特别是如果你有很多子视图,但对于简单的应用程序它应该可以解决问题。

我以一种更复杂但性能更高的方式解决了这个问题,但是对我的应用程序的动画引擎使用单例/管​​理器,并且任何时候文本字段成为响应者,我都会将其分配给一个静态的,它将得到根据某些其他事件席卷(辞职)......我几乎不可能在一段中解释。

要有创意,在我发现这个问题后,我只花了 10 分钟就为我的应用考虑了这个问题。

于 2010-09-10T21:04:44.413 回答
0

最简单的方法是调用方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    if(![txtfld resignFirstResponder])
    {
        [txtfld resignFirstResponder];
    }
    else
    {

    }
    [super touchesBegan:touches withEvent:event];
}
于 2010-12-22T14:33:54.807 回答
0

我最近需要使用的一种更强大的方法:

- (void) dismissKeyboard {
    NSArray *windows = [UIApplication sharedApplication].windows;

    for(UIWindow *window in windows) [window endEditing:true];

    //  Or if you're only working with one UIWindow:

    [[UIApplication sharedApplication].keyWindow endEditing:true];
}

我发现其他一些“全局”方法不起作用(例如,UIWebView&WKWebView拒绝辞职)。

于 2015-03-09T06:04:36.460 回答
0

将一个点击手势识别器添加到您的视图中。并将其定义为 ibaction

你的 .m 文件会像

    - (IBAction)hideKeyboardGesture:(id)sender {
    NSArray *windows = [UIApplication sharedApplication].windows;
    for(UIWindow *window in windows) [window endEditing:true];
    [[UIApplication sharedApplication].keyWindow endEditing:true];
}

它对我有用

于 2015-03-24T11:23:47.727 回答
0

是的,endEditing 是最好的选择。从 iOW 7.0 开始,UIScrollView有一个很酷的功能可以在与滚动视图交互时关闭键盘。为此,您可以设置keyboardDismissMode.UIScrollView

将键盘关闭模式设置为:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag

它几乎没有其他类型。看看这个苹果文档

于 2016-07-01T10:02:30.890 回答
0

迅速:

self.view.endEditing(true)
于 2016-07-05T14:06:32.760 回答
0

您必须使用其中一种方法,

[self.view endEditing:YES];

或者

[self.textField resignFirstResponder];
于 2016-09-14T08:15:13.377 回答
0

更新

我找到了另一种简单的方法

只需声明一个属性:-

@property( strong , nonatomic) UITextfield *currentTextfield;

和一个 Tap 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];

 }
于 2016-10-05T06:07:08.593 回答