当用户触摸UIView时隐藏键盘

29

我有一个带有多个文本框的UIView。现在我已经使用代理将响应者从一个文本字段更改为另一个文本字段。在这种情况下,当用户到达最后一个文本框时,我的键盘会消失。

但现在我想在用户触摸UIView时(除了文本框之外的任何屏幕位置),隐藏我的键盘。有人能帮我吗?

谢谢

11个回答

43

在touchesBegan方法中使用resignFirstResponder,如下所示:

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

如果您不确定当前焦点所在的位置,可能需要在多个文本字段上调用此方法;我没有测试过这种情况。

另外,在界面构建器中,您需要启用视图的“用户交互启用”复选框,或者通过编程实现:

myView.userInteractionEnabled = YES;

但是在哪里调用resignFirstResponder呢?如何知道用户触摸了UIView? - nbojja
1
我已经编辑了帖子,在touchesBegan中包含了一个示例。 - PCheese
嘿,谢谢你的帮助。使用UIView时效果很好。但是我有另一种情况,即在UITableView中有文本框。在这种情况下,你的代码不起作用。我对iPhone开发非常陌生,请…… - nbojja
如果你想找出要调用resignFirstResponder的控件,可以使用isFirstResponder。所以在我的代码中,我会这样写:"if ([myTextField isFirstResponder]) [myTextField resignFirstResponder]; else if..."。或许可以更系统地遍历子视图,在UIResponder类型的视图/控件中进行相同的检查。 - pschang
评论:它不能与UIScrollViews一起使用。 - cV2
或者你可以调用 [UIApplication.sharedApplication sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil]; 如果你不知道哪个textField是第一响应者。 - Bejil

26

当您想要隐藏键盘时,只需在您的视图控制器中调用以下代码:

[self.view endEditing:NO];


(注:上述代码为Objective-C语言中的代码,作用是隐藏当前正在显示的键盘。)

14

我使用

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
     UITouch *touch = [touches anyObject];
     if(touch.phase==UITouchPhaseBegan){
         //find first response view
         for (UIView *view in [self.view subviews]) {
             if ([view isFirstResponder]) {
                 [view resignFirstResponder];
                 break;
             }
         }
     }
}

简单,简洁,完全通用。非常好! - ryan0

3
根据《Beginning iPhone Development》,你需要绘制一个圆角矩形按钮,使其覆盖整个UI即整个屏幕。然后进入布局菜单,点击发送到背面。接下来,在检查器中将按钮类型从圆角矩形更改为自定义。现在给此按钮添加一个触摸内部事件,并将其附加到处理它的方法上。在此方法的主体中,请确保您有以下语句:
[myTextFieldOne resignFirstResponder];
[myTextFieldTwo resignFirstResponder];

基本上,将resignFirstResponder消息发送到您的每个文本字段或任何可以产生键盘的字段。

实际上,我对iPhone SDK非常陌生。我不知道这是否是最好的方法,但它有效,并且是我从上述书籍中学到的。希望能有所帮助。


你确定你的建议符合MVC模式吗? - Malloc

3
一个超级简单的方法是按照PCheese所说的方式进行操作。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
if(touch.phase == UITouchPhaseBegan) {
    [self.view endEditing:YES];
}

我之前在按钮事件中使用了[self.view endEditing:YES],但是当与之前的答案结合使用时,它可以很好地工作。更加简单,而且您不需要做任何其他操作 - 只需将其放在.m文件中即可。此外,这适用于所有(至少就我所见)文本字段(适用于UITextField和UITextView)。

我知道楼主可能已经不再需要这个,但我只是想与其他遇到相同问题的人分享。


2

2

谢谢Blaenk,我一直在尝试如何做到这一点,没有意识到我可以将按钮放在背景中,真是个好技巧!这是我的贡献(对于这个网站和Cocoa Touch都是新手,所以它可能不是最稳健的代码,但到目前为止它还在工作...):

我从我的UIButton的touchUpInside事件中调用此方法:

-(void)closeKeyboard:(id)sender {
    UIView *theFirstResponder = [self findFirstResponder];
    if (theFirstResponder) {
        [theFirstResponder resignFirstResponder];
    }
}

在这个循环中找到firstResponder:

- (UIView *)findFirstResponder {  
    UIView *firstResponderView = nil;
    for (UIView *view in [self entryFields]) {  
        if ([view isFirstResponder]) {  
            firstResponderView = view;
            break;
        }
    }   
    return firstResponderView;  
}

这取决于视图中的每个UITextField控件都有一个tag(可以在Interface Builder中完成)。

这只是我的个人意见,但我想回馈一些东西!


2

所以我煞费苦心终于弄明白了...

你不需要其他按钮或任何东西。

你只需要选择 "文件拥有者",在检查器中从其 textField 输出 (或您命名的任何内容) 拖动到您实际的文本字段上(通过您命名的任何内容)。这将是除了您已经连接的任何输入之外的一个额外步骤。

当然,在控制输出(UIView 通过检查器更改为 UIControl) 到文件拥有者 via backgroundtouched... 这是我们所有人试过的第一件事。


1
将类UIView从检查器的标识选项卡更改为类UIControl。 添加以下内容:
- (IBAction)tabBackground:(id) sender;

将此代码添加到您的.h文件中。
将以下代码添加到您的.m文件中:
- (IBAction)tabBackgroup:(id) sender {
    [nameField resignFirstRespnder];
    [numberField resignFirstResponder];
}

从检查器中连接您的tabBackground,将操作接收部分连接到UIView(它是UIControl),然后您就可以开始了。


1
最适当的解决此问题的方法是使用以下方法:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    if(![touch.view isMemberOfClass:[UITextField class]]) {
        [touch.view endEditing:YES];
    }
}

注意:此方法不适用于UIScrollView实例。

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