提问



我的桌子中有很多控制台分散在我的桌子中,我想知道是否有一种更简单的方法来解除键盘,而不必遍历所有控件并将它们全部作为第一响应者辞职。我猜问题是..如何让当前的第一响应者进入键盘?

最佳参考


尝试:点击
[self.view endEditing:YES];

其它参考1


您可以强制当前编辑视图使用[view endEditing:YES]重新调整其第一响应者状态。这隐藏了键盘。


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


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

其它参考2


您可以向应用程序发送零目标操作,它将在任何时候终止第一响应者,而不必担心哪个视图当前具有第一响应者状态。


Objective-C的:


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


Swift 3.0:


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


Nil目标操作在Mac OS X上常用于菜单命令,这里有一个在iOS上使用它们。

其它参考3


老实说,我对这里提出的任何解决方案并不感到沮丧。我确实找到了一种很好的方法来使用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,而不是滑动。因此,如果您在键盘上方滚动内容,则滑动仍会滚动并显示键盘。通过在键盘消失后移除手势识别器,可以正常处理视图上的未来点击。

其它参考4


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





考虑这种情况:


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


我在viewDidLoad中这样做


- (void)viewDidLoad 
{
    [super viewDidLoad];

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


并且viewcontroller实现了可选方法


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


无论你在哪个文本区域,只要我按下键盘上的return,就会被解雇!


在你的情况下,只要你将所有textfield的委托设置为self并实现textFieldShouldReturn,同样的方法就可以了。

其它参考5


更好的方法是让某些东西窃取第一响应者状态。


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


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


如果做不到这一点,请创建一个具有零大小框架的新UITextField,将其添加到某个地方的视图并执行类似的操作(之后再进行重新签名)。

其它参考6


把它放在一些实用类中。


+ (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];
    }
}

其它参考7


@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;的回答的修正案。如果您在整个应用中依赖这些通知,则禁用文本字段将阻止发送UIKeyboardWillShowNotificationUIKeyboardWillHideNotification键盘通知。

其它参考8


这里有很多过于复杂的答案,也许是因为这在iOS文档中并不容易找到。约瑟夫H就在上面:


[**view window] endEditing:YES];

其它参考9


当用户触摸UITextField或键盘外部屏幕上的任何位置时,快速提示如何关闭iOS中的键盘。考虑到iOS键盘可以占用多少空间,让用户轻松直观地关闭键盘是有意义的。


这是一个链接[66]

其它参考10


甚至比Meagar的答案更简单


覆盖touchesBegan:withEvent:


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


当你触摸background中的任何地方时dismiss the keyboard会这样。

其它参考11


在视图控制器的头文件中添加<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;
}

其它参考12


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


在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];
}

其它参考13


你应该endEditing:发送工作窗口作为UIView的子类


[**UIApplication sharedApplication].windows.firstObject endEditing:NO];

其它参考14


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


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

其它参考15


Jeremy的回答并不适合我,我想因为我在标签视图中有一个导航堆栈,顶部有一个模态对话框。我现在正在使用以下内容,它对我有用,但你的里程可能会有所不同。


 // 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];

}

其它参考16


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

其它参考17


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


在子类中放这个代码..


-(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];
}


在textfield委托中(类似于textview委托)


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


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


全部设置..现在只需在代码中的任何位置发布通知。它将辞去任何键盘。

其它参考18


我们可以迅速做到


UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)

其它参考19


弹出键盘后关闭键盘, 2例



  1. 当UITextField在UIScrollView 中

  2. 当UITextField在UIScrollView 之外



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


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


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



  1. 滚动视图中,点击外部不会触发任何事件,因此在这种情况下使用点击手势识别器
    拖放滚动视图的 UITapGesture ,然后为其创建IBAction



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


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


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


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


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

其它参考20


从UITableView和UIScrollView中解除键盘的最佳方法是:


tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag

其它参考21


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


这样做不应该这么难......

其它参考22


它不漂亮,但是当我不知道响应者是什么时,我辞职第一个响应者的方式:


在IB中或以编程方式创建UITextField。把它隐藏起来。如果您在IB中创建它,请将其链接到您的代码。
然后,当您想要关闭键盘时,将响应者切换到不可见的文本字段,并立即将其重新签名:


  [self.invisibleField becomeFirstResponder];
  [self.invisibleField resignFirstResponder];

其它参考23


您可以递归遍历子视图,存储所有UITextField的数组,然后遍历它们并将它们全部重新签名。


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


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


有创意,在我发现这个问题后,我花了10分钟时间为我的应用程序考虑一下。

其它参考24


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


- (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拒绝辞职。

其它参考25


在您的视图中添加一个Tap Gesture Recognizer。并定义它ibaction


你的.m文件就像


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


它对我有用

其它参考26


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


将键盘关闭模式设置为:


tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag


它几乎没有其他类型。看看这个苹果文件。[68]

其它参考27


在迅捷:


self.view.endEditing(true)

其它参考28


最简单的方法是调用方法


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

    }
    [super touchesBegan:touches withEvent:event];
}

其它参考29


你必须使用这些方法之一,


[self.view endEditing:YES];


要么


[self.textField resignFirstResponder];