iPhone键盘,完成按钮和resignFirstResponder

51

这可能是一个愚蠢的问题,但我在文档中找不到答案。在弹出键盘上,“完成”按钮总是会导致键盘消失吗?我在网上看到了很多像这样的代码:

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
    [theTextField resignFirstResponder];
    return YES;
}
当我按下“完成”按钮时,键盘会弹下并使UITextField放弃第一响应者。我认为按下“完成”按钮以前不会导致UITextField放弃第一响应者,但这种行为在某个时候发生了改变。我是在OS 3.0-3.1.3上进行调试的。

1
请参阅 https://developer.apple.com/library/ios/#documentation/iphone/conceptual/iPhone101/Articles/05_ConfiguringView.html。 - user1200790
1
显然我没有足够的声望来评论Nevan King的答案,所以我在这里提一下,对于他的解决方案,不需要将类设置为UITextFieldDelegate。UITextFieldDelegate协议只是定义了一些消息发送给委托人,询问文本字段是否应该放弃第一响应者等等...任何对象都可以通过像他的答案中所做的那样定义它们的方法来接收操作,从而实现它。 - Robert Hawkey
5个回答

93

我创建了一个小的测试项目,只包含一个UITextField和这段代码

#import <UIKit/UIKit.h>
@interface TextFieldTestViewController : UIViewController
<UITextFieldDelegate>
{
    UITextField *textField;
}
@property (nonatomic, retain) IBOutlet UITextField *textField;
@end

#import "TextFieldTestViewController.h"
@implementation TextFieldTestViewController
@synthesize textField;

- (void)viewDidLoad
{
    [self.textField setDelegate:self];
    [self.textField setReturnKeyType:UIReturnKeyDone];
    [self.textField addTarget:self
                  action:@selector(textFieldFinished:)
        forControlEvents:UIControlEventEditingDidEndOnExit];
    [super viewDidLoad];
}
- (IBAction)textFieldFinished:(id)sender
{
    // [sender resignFirstResponder];
}

- (void)dealloc {
    [super dealloc];
}
@end
文本字段是未经修改的UITextField拖放到NIB上,并连接了outlet。
加载应用程序后,单击文本字段会弹出键盘。按下“完成”按钮将使文本字段失去焦点并动画退出键盘。请注意,网络上的建议始终使用[sender resignFirstResponder],但没有它也可以正常工作。

嗯。 addTarget:action:forControlEvents: 是什么?setDelegate: 不够吗?让我自己试试。 - bealex
是的,没错。如果你移除 addTarget:... 这个调用,一切都会正常。 - bealex
1
对于像我这样的新手,使用 Interface Builder 完成此操作的方法是从“Did End On Exit”拖动 + 到文件所有者,然后将其分配给一个不执行任何操作的 IBAction(在本例中为 textFieldFinished:(id)sender)。上面的答案是正确的,只是想要补充一下。 - Paul Wieland
如果仍然无法正常工作,请查看此问题:https://dev59.com/sXA75IYBdhLWcg3wS3BA - Vladimir Grigorov

15

在 Xcode 5.1 中

启用“完成”按钮

  • 在Storyboard中的UITextField的属性检查器中,找到"Return Key"字段并选择 "Done"

当按下"完成"时隐藏键盘

  • 在Storyboard中将您的ViewController设置为UITextField的委托
  • 将此方法添加到您的ViewController中

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

添加 Swift 代码作为参考:func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() return true } - Rom

6

从文档中(任何版本):

在您选择的时间,您的应用程序有责任关闭键盘。您可以根据特定用户操作关闭键盘,例如用户在您的用户界面中点击特定按钮。您还可以配置文本字段委托,在用户在键盘上按“返回”键时关闭键盘。要关闭键盘,请向当前是第一响应者的文本字段发送resignFirstResponder消息。这样做会导致文本字段对象结束当前编辑会话(经过委托对象的同意)并隐藏键盘。

因此,您必须以某种方式发送resignFirstResponder。但是,在处理textFieldShouldReturn:消息期间,文本字段失去焦点的可能性也存在。这也会导致键盘消失。


谢谢您的回答。我找到了导致 UITextField 放弃第一响应者的部分。我有一个调用 [textField addTarget:self action:@selector(textFieldDone:) forControlEvents:UIControlEventEditingDidEndOnExit]。奇怪的是,textFieldDone: 方法是空的(我删除了 resignFirstResponder 调用)。所以我仍然无法弄清楚为什么键盘会消失。 - nevan king
你可能会隐式地将焦点移动到另一个组件上吗?例如通过更改表格或标签中的某个值? - bealex
我认为没有其他事情发生。我创建了一个小项目(下面发布了代码),它给出了相同的行为。不太确定为什么会发生这种情况。 - nevan king
nevan,你的解决方案很好用。我在一个带有done键盘的tableview cell中有一个textfield。当输入为空时,done键无法关闭键盘。添加了addTarget代码后,现在可以关闭键盘了。 - CF_Maintainer

2

Done按钮的一行代码:

[yourTextField setReturnKeyType:UIReturnKeyDone];

在TextField的valueChanged事件上添加操作方法,并添加以下代码-
[yourTextField resignFirstResponder];

0

我使用了这种方法来改变选择文本框

- (BOOL)textFieldShouldReturn:(UITextField *)textField {

if ([textField isEqual:self.emailRegisterTextField]) {

    [self.usernameRegisterTextField becomeFirstResponder];

} else if ([textField isEqual:self.usernameRegisterTextField]) {

    [self.passwordRegisterTextField becomeFirstResponder];

} else {

    [textField resignFirstResponder];

    // To click button for registration when you clicking button "Done" on the keyboard
    [self createMyAccount:self.registrationButton];
}

return YES;

}


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