如果用户点击屏幕键盘之外的区域,我该如何关闭键盘?

42

我希望能够在用户点击键盘范围外的任何地方时关闭iPhone键盘。我应该怎么做?我知道我需要关闭当前响应者,但不知道如何在用户在键盘区域之外点击时实现它。


你可能会发现这个有用:https://github.com/michaeltyson/TPKeyboardAvoiding - Brian Donovan
10个回答

85
你需要添加一个UITapGestureRecogniser并将其分配给视图,然后在选择器上调用resign first responder以使文本字段失去第一响应者。
代码:
在viewDidLoad中。
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                      action:@selector(dismissKeyboard)];

[self.view addGestureRecognizer:tap];

dismissKeyboard:

-(void)dismissKeyboard {
       [aTextField resignFirstResponder];
}

(其中aTextField是负责键盘的文本框)

选项2

如果您无法添加手势识别器,则可以尝试这个方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch * touch = [touches anyObject];
    if(touch.phase == UITouchPhaseBegan) {
        [aTextField resignFirstResponder];
    }
}

手势识别器非常优雅的解决方案! - Sheehan Alam
4
这很好,但手势操作会占用视图上的所有按钮点击事件。有什么想法吗? - kmehta
在iOS中解决键盘消失的好方法。 - IOS Rocks
3
我认为这很棒,但它会覆盖其他输入,如 CollectionViews。请参见下面 Matt Rees 的评论以进行修复。 - Jim True
在Swift中,应该使用touches.first而不是[touches anyObject] - Vadim Bulavin

46

我使用过的最简单的解决方案是:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

      [self.view endEditing:YES];

}

endEditing命令可用于包含您的文本字段作为子视图的任何视图上。此方法的另一优点是您不需要知道哪个文本字段触发了键盘。因此,即使您有多个文本字段,只需将此行添加到父视图即可。

根据苹果的文档,我认为这种方法存在特别是为了解决这个问题。


那么UIScrollView呢? - testing
这绝对是最好的解决方案! - StackUnderflow
尝试在UIScrollView中添加以下代码: scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; - Reza Dehnavi

16

添加一个tap手势识别器,但确保cancelsTouchesInView = NO。

UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(closeTextInput)];
tapGesture.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapGesture];
[tapGesture release];

关于tapGesture.cancelsTouchesInView = NO的观点非常好,非常感谢! - Miros

3
您需要添加一个UITapGestureRecogniser并将其分配给视图,然后在其选择器上调用textfield的resign first responder。
代码如下:
在viewDidLoad中:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                      action:@selector(dismissKeyboard)];

[self.view addGestureRecognizer:tap];

在dismissKeyboard函数中:

-(void)dismissKeyboard {
       [self.view endEditing:true];
}

1

您需要添加一个透明的UIVIew作为键盘下方的子视图,并在那里处理触摸事件,以关闭键盘。以下代码供您参考。

UITapGestureRecognizer* gesture = [[UITapGestureRecognizer alloc]   initWithTarget:self action:@selector(overlayTouched:)]; 
gesture.delegate = self;
[(UITapGestureRecognizer *)gesture setNumberOfTouchesRequired:1];

UIView* trans = [[UIView alloc] initWithFrame:[[delegate view] bounds]];
[trans setOpaque:NO];
[trans setAutoresizingMask:UIViewAutoresizingFlexibleWidth |    UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin];
[trans setAlpha:0.3];
[trans setUserInteractionEnabled:YES];
trans.multipleTouchEnabled = YES;
[trans addGestureRecognizer:gesture];
[trans setBackgroundColor:[UIColor blackColor]];
[trans setTag:BLACK_SCREEN_VIEW];

1
这是一个 Swift 4 的解决方案:
 let tap = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard))

 self.view.addGestureRecognizer(tap)

并且dismissKeyboard

@objc func dismissKeyboard() {
    self.view.endEditing(true)
}

0

如果您正在使用UITableViewController或者有一个用户将要与之交互的UITableView,那么在您的ViewDidLoad中可以简单地执行以下操作:

tableView.KeyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag;

注意:这是 Xamarin.iOS 的语法。


0

你甚至不需要手势识别器。视图可以在没有手势识别器的情况下检测触摸。你所需要的就是在你的视图控制器中加入这个代码...

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

      [self.view endEditing:YES];

}

0

另一种方法很简单:

在界面构建器中将您的UIView作为UIControl放入自定义类中,然后您可以在UIView : UIControlTouch up inside event中附加一个IBAction方法,接着您可以在IBAction method中放置[yourTextField resignFirstResponder],像这样:

- (IBAction) hideKeyboard: (id) sender
{
    // If you have more than one textfield to dismiss, of course only can be active 1, but here you can't know who is it, because sender will be the UIView : UIControl
    [alias resignFirstResponder];
    [password resignFirstResponder];
}

其次,你还有另一种选择,就是在界面构建器中将 键盘的Return键设置为Done(可以是任何一个你想要的按键,但是Done对于这个操作很好,因为返回意味着执行表单操作),这样你就可以按下 Done 隐藏键盘,但在这种情况下,你必须将之前的IBAction方法附加到 Did end on exit 事件。

以这种方式,键盘将通过 触摸屏幕外部 或者 点击键盘上的Done 来隐藏。

如果你想改进代码,如果只有通过点击键盘上的 Done 才会隐藏键盘,那么该方法应该是:

// Attach all textFields here on Did end on exit event, will not work if touch outside the keyboard
- (IBAction) hideKeyboard: (id) sender
{
      [sender resignFirstResponder];
}

0

如果您不想添加手势识别器,也可以使用touchesBegin方法

Swift 4代码

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { view.endEditing(true) }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接