编辑 UITextField 时如何关闭键盘
Posted
技术标签:
【中文标题】编辑 UITextField 时如何关闭键盘【英文标题】:How do you dismiss the keyboard when editing a UITextField 【发布时间】:2010-09-21 10:03:55 【问题描述】:我知道当我想关闭键盘时,我需要告诉我的 UITextField 让第一响应者辞职,但我不确定如何知道用户何时按下了键盘上的“完成”键。有我可以关注的通知吗?
【问题讨论】:
[self.view endEditing:YES];在接触开始代表是最好的解决方案 【参考方案1】:我将UITextField
的代表设置为我的ViewController
类。
在那个类中,我实现了这个方法如下:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
[textField resignFirstResponder];
return NO;
【讨论】:
参见上面的例子...将使用 IntefaceBuilder 连接到您用作控制器的任何操作上...每当用户关闭文本输入系统(按下完成),这将是调用... 这两种方法中的任何一种都可以 - 当用户点击 Return(“Done”,随便什么)键时,文本字段会发送其操作,并且还会发送其委托 -textFieldShouldReturn:。 顺便说一句 - 这也适用于 UISearchBar。例如,我的代码中有一个成员 IBOutlet searchBarTusb;当我的“返回键”(UIReturnKeySearch)被点击时,-(void)searchBarSearchButtonClicked:,我把语句[searchBarTusb resignFirstResponder];另请注意,“返回键”是使用 Interface Builder 在 NIB 中设置的。 为什么返回NO
而不是YES
?
@IulianOnofrei 返回按钮的默认行为是添加一行返回并保持键盘在屏幕上。通过返回NO
,您可以避免在文本中添加行返回。【参考方案2】:
如果您将文本字段的 DidEndOnExit 事件连接到 InterfaceBuilder 中的操作 (IBAction),则会在用户关闭键盘(使用返回键)时收到消息,并且发送者将是对触发的 UITextField 的引用事件。
例如:
-(IBAction)userDoneEnteringText:(id)sender
UITextField theField = (UITextField*)sender;
// do whatever you want with this text field
然后,在 InterfaceBuilder 中,将文本字段的 DidEndOnExit 事件链接到控制器上的此操作(或您用来链接 UI 事件的任何东西)。每当用户输入文本并关闭文本字段时,控制器都会收到此消息。
【讨论】:
唯一看起来可能有效的事件是 textFieldDidEndEditing,它指出它仅在 UITextField 退出第一响应者状态后发送。我如何知道何时需要辞去急救人员身份? 我对术语感到抱歉......这不是一个实际的通知(事件)......我将用一个简单的例子和解释来编辑我的答案,所以请看:) 为了澄清这个答案,当您按下返回键时,textField 会发送“退出时结束”事件,因此您需要链接到控制器。我认为这种方法比我上面概述的方法更容易。 您能否编辑此答案,使其提及要连接的哪个事件?这显然比设置委托要好。 想要支持这个答案,但在它提到 DidEndOnExit 事件之前不能。如果 OP 不会,请有编辑权限的人进行更改?【参考方案3】:你也可以在你的控制器中创建一个方法
-(IBAction)editingEnded:(id)sender
[sender resignFirstResponder];
然后在 IB 的 Connection Inspector 中将 Event "Did End On Exit" 连接到它。
【讨论】:
这几乎是不正确的,或者至少它没有抓住重点。通过订阅DidEndOnExit
事件,您无需调用resignFirstResponder
。您可以通过在[UIResponder resignFirstResponder]
上放置一个符号断点来测试它。请注意,即使您不调用 resignFirstResponder,它仍然会被系统调用。这在 Matt Neuburg 的优秀书籍中有解释:apeth.com/iosBook/…【参考方案4】:
库比,谢谢。您的代码有效。就像你说的那样明确(对于新手来说)你必须将UITextField
的delegate
设置为等于文本字段所在的ViewController。您可以随心所欲地执行此操作。我选择了viewDidLoad
方法。
- (void)viewDidLoad
// sets the textField delegates to equal this viewController ... this allows for the keyboard to disappear after pressing done
daTextField.delegate = self;
【讨论】:
如果您将文本字段添加到情节提要或 NIB,您也可以在此处设置文本字段的delegate
。您不必以编程方式执行此操作,如上所示。两种方法都可以正常工作。【参考方案5】:
这是一个无需代码即可获得自动键盘关闭行为的技巧。在 nib 中,编辑 Identity inspector 中的 First Responder 代理对象,添加一个新的 First Responder 动作;我们称之为dummy:
。现在将文本字段的 Did End on Exit 事件挂钩到 First Responder 代理对象的 dummy:
操作。而已!由于文本字段的 Did End on Exit 事件现在有一个动作-目标对,所以当用户点击 Return 时,文本字段会自动关闭其键盘;并且由于没有为向上发送到响应者链的消息找到处理程序不会受到惩罚,因此即使在任何地方都没有实现 dummy:
,应用程序也不会崩溃。
【讨论】:
@matt 我发现如果我添加一个展开转场并连接 didEndOnExit 事件,那么在按下 Return 时将触发展开转场。如果没有事件连接,则不会触发 segue。很棒,但是嗯?有什么意见吗?顺便说一句:我有你的 Swift(完成)和 iOS10(第 6 章)书籍。他们对我帮助很大! @Verticon 问题和答案与segues无关,所以我不明白这个问题...... :(这纯粹是关于键盘解雇 @matt 对不起,伙计。我很支持,因为 1)我在处理如何处理 UITextField 的返回键时遇到了这个线程; 2)这是一个与您互动的机会(感谢 da 书籍)。没有“问题”。只是我对它为什么/如何工作的方式缺乏了解。 @Verticon 无法提供帮助,我深表歉意。随意提出一个包含更多信息的新问题(演示项目?),如果我有用的话,请告诉我。 @matt 谢谢***.com/questions/47289747/…【参考方案6】:只需添加
[textField endEditing:YES];
您要在哪里禁用键盘并显示选择器视图。
【讨论】:
【参考方案7】:在 Swift 中,您可以在 Controller 中编写 IBAction,并将文本字段的 Did End On Exit 事件设置为该操作
@IBAction func returnPressed(sender: UITextField)
self.view.endEditing(true)
【讨论】:
【参考方案8】:Swift 4.2
它将 100% 工作
import UIKit
class ViewController: UIViewController, UITextFieldDelegate
@IBOutlet weak var textField: UITextField!
override func viewDidLoad()
super.viewDidLoad()
self.textField.delegate = self
// hide key board when the user touches outside keyboard
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
self.view.endEditing(true)
// user presses return key
func textFieldShouldReturn(_ textField: UITextField) -> Bool
textField.resignFirstResponder()
return true
【讨论】:
我很感激这个答案还教会了我如何在用户触摸键盘外部时关闭键盘。【参考方案9】:你也可以使用
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
[self.yourTextField resignFirstResponder];
如果你有很多 Uitextfields 最好的一个:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
[self.view endEditing:YES];
【讨论】:
【参考方案10】:这是我必须做的才能让它工作,我认为对于任何有数字小键盘的人(或任何其他没有完成按钮的人)来说都是必要的:
-
我将 ViewController 中的 UIView 更改为 UIControl。
我创建了一个名为
的函数-(IBAction)backgroundIsTapped:(id)sender
这也在 .h 文件中定义。
在此之后,我在 Interface Builder 中链接到 ViewController 的“touch down”位。
在'背景被点击'功能中,我放了这个:
[answerField resignFirstResponder];
只需记住将“answerField”更改为您要从中删除键盘的 UITextField 的名称(显然请确保您的 UITextField 定义如下:)
IBOutlet UITextField * <nameoftextfieldhere>;
我知道这个话题可能很久以前就死了......但我希望这会在某个地方对某人有所帮助!
【讨论】:
..但如果用户点击另一个控件,它就不能很好地工作。【参考方案11】:您会注意到“textFieldShouldReturn”方法提供了已按下 DONE 键的文本字段对象。如果您设置标签,您可以打开该文本字段。或者您可以跟踪对象的指针并将其与其创建者存储的某些成员值进行比较。
我的自学方法是这样的:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
NSLog(@"%s", __FUNCTION__);
bool fDidResign = [textField resignFirstResponder];
NSLog(@"%s: did %resign the keyboard", __FUNCTION__, fDidResign ? @"" : @"not ");
return fDidResign;
同时,我进行了否定辞职的“验证”测试。这只是为了说明,所以如果用户输入 NO!进场,它不会解散。行为如我所愿,但输出顺序与我预期不同。
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
NSLog(@"%s", __FUNCTION__);
if( [[textField text] isEqualToString:@"NO!"] )
NSLog(@"%@", textField.text);
return NO;
else
return YES;
以下是我拒绝接受的 NSLog 输出。您会注意到我正在返回辞职结果,但我希望它返回 FALSE 给我以向调用者报告?!除此之外,它还有必要的行为。
13.313 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:] 13.320 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldEndEditing:] 13.327 StudyKbd[109:207] 不! 13.333 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:]:确实放弃了键盘 59.891 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:] 59.897 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldEndEditing:] 59.917 StudyKbd[109:207] -[StudyKbdViewController doneEditText]:否 59.928 StudyKbd[109:207] -[StudyKbdViewController textFieldShouldReturn:]:确实放弃了键盘【讨论】:
你能解释一下吗..如果我在两种情况下都返回 NO 或 YES 会发生同样的事情,那么在 textFieldShouldReturn 委托方法中返回 yes 的需要是什么【参考方案12】:这是一种非常简洁的方法,可以使用 Return 键或在后台触摸来结束版本。
在界面生成器中,将字段嵌入到 UIFormView 类的视图中
这个类是做什么的:
自动将自身附加为字段委托(从 nib 唤醒或手动添加) 保留对当前编辑字段的引用 返回时关闭键盘或在后台触摸代码如下:
接口
#import <UIKit/UIKit.h>
@interface UIFormView : UIView<UITextFieldDelegate>
-(BOOL)textFieldValueIsValid:(UITextField*)textField;
-(void)endEdit;
@end
实施
#import "UIFormView.h"
@implementation UIFormView
UITextField* currentEditingTextField;
// Automatically register fields
-(void)addSubview:(UIView *)view
[super addSubview:view];
if ([view isKindOfClass:[UITextField class]])
if ( ![(UITextField*)view delegate] ) [(UITextField*)view setDelegate:self];
// UITextField Protocol
-(void)textFieldDidBeginEditing:(UITextField *)textField
currentEditingTextField = textField;
-(void)textFieldDidEndEditing:(UITextField *)textField
currentEditingTextField = NULL;
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
[self endEdit];
- (BOOL)textFieldShouldReturn:(UITextField *)textField
if ([self textFieldValueIsValid:textField])
[self endEdit];
return YES;
else
return NO;
// Own functions
-(void)endEdit
if (currentEditingTextField)
[currentEditingTextField endEditing:YES];
currentEditingTextField = NULL;
// Override this in your subclass to handle eventual values that may prevent validation.
-(BOOL)textFieldValueIsValid:(UITextField*)textField
return YES;
@end
通过子类化表单并覆盖
textFieldValueIsValid:
方法,你
如果给定的值不正确,可以避免版本结束
字段。
如果某个字段在 Interface Builder 中设置了委托,则表单不会更改它。我看不出有很多理由为特定字段设置不同的委托,但为什么不……
有很多方法可以改进这个表单视图类 - 附加一个委托,做一些布局,当键盘覆盖一个字段时处理(使用 currentEditingTextField 框架),自动开始下一个字段的编辑,...
我个人将它保存在我的框架中,并始终将其子类化以添加功能,它通常“按原样”有用。
我希望它会有所帮助。祝大家好运
【讨论】:
实用类。一个小点,你不应该在你自己的类前面加上“UI”。在objective-c中你应该使用你自己的前缀(“TL”?),在Swift中,不要使用任何东西。 谢谢@kubi。这是正确的。它是我框架中的 MF,例如 MooseFactory ;)【参考方案13】:如果你想在 UIViewController 中进行所有编辑,你可以使用。
[[self view]endEditing:YES];
如果您想关闭特定的 UITextField 键盘隐藏,请使用。
1.在 viewcontroller.h 中添加委托
<UITextFieldDelegate>
使委派无法访问您的文本字段。
self.yourTextField.delegate = self;
将此方法添加到您的视图控制器中。
-(BOOL)textFieldShouldEndEditing:(UITextField *)textField [textField resignFirstResponder]; 返回是;
【讨论】:
【参考方案14】:在 swift 3 中以编程方式设置 UITextField 的委托
在您的 ViewController.Swift 文件中实现 UITextFieldDelegate(例如 class ViewController: UIViewController, UITextFieldDelegate )
lazy var firstNameTF: UITextField =
let firstname = UITextField()
firstname.placeholder = "FirstName"
firstname.frame = CGRect(x:38, y: 100, width: 244, height: 30)
firstname.textAlignment = .center
firstname.borderStyle = UITextBorderStyle.roundedRect
firstname.keyboardType = UIKeyboardType.default
firstname.delegate = self
return firstname
()
lazy var lastNameTF: UITextField =
let lastname = UITextField()
lastname.placeholder = "LastName"
lastname.frame = CGRect(x:38, y: 150, width: 244, height: 30)
lastname.textAlignment = .center
lastname.borderStyle = UITextBorderStyle.roundedRect
lastname.keyboardType = UIKeyboardType.default
lastname.delegate = self
return lastname
()
lazy var emailIdTF: UITextField =
let emailid = UITextField()
emailid.placeholder = "EmailId"
emailid.frame = CGRect(x:38, y: 200, width: 244, height: 30)
emailid.textAlignment = .center
emailid.borderStyle = UITextBorderStyle.roundedRect
emailid.keyboardType = UIKeyboardType.default
emailid.delegate = self
return emailid
()
// 标记:- 处理委托文本字段..
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
view.endEditing(true)
func textFieldShouldReturn(_ textField: UITextField) -> Bool
if textField == firstNameTF
lastNameTF.becomeFirstResponder()
else if textField == lastNameTF
emailIdTF.becomeFirstResponder()
else
view.emailIdTF(true)
return true
【讨论】:
【参考方案15】:创建一个函数 hidekeyboard 并将其链接到 .xib 文件中的文本字段并选择 DidEndOnExit
-(IBAction)Hidekeyboard
textfield_name.resignFirstResponder;
【讨论】:
【参考方案16】:如果您使用 Interface Builder 创建了视图,请使用以下内容 只需创建一个方法,
-(IBAction)dismissKeyboard:(id)sender
[sender resignFirstResponder];
只需右键单击视图中的文本字段,并将事件设置为退出时结束,并将其连接到方法“dismissKeyboard”。
初学者的最佳指南是 “Head First iPhone 和 iPad 开发,第 2 版”
【讨论】:
【参考方案17】:试试这个
- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
if ([text isEqualToString:@"\n"])
[textView resignFirstResponder];
return NO;
return YES;
【讨论】:
【参考方案18】://====================================================
// textFieldShouldReturn:
//====================================================
-(BOOL) textFieldShouldReturn:(UITextField*) textField
[textField resignFirstResponder];
if(textField.returnKeyType != UIReturnKeyDone)
[[textField.superview viewWithTag: self.nextTextField] becomeFirstResponder];
return YES;
【讨论】:
【参考方案19】:任何寻找 Swift 3
的人1) 确保您的 UITextField's Delegate 已连接到 Storyboard 中的 ViewController
2) 在您的 ViewController.Swift 文件中实现 UITextFieldDelegate(例如 class ViewController: UIViewController, UITextFieldDelegate )
3) 使用下面的委托方法
func textFieldShouldReturn(textField: UITextField) -> Bool
textField.resignFirstResponder()
return false
【讨论】:
【参考方案20】:这就是我在 Swift 4.2 中关闭键盘的方式,它适用于我:
override func viewDidLoad()
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action:
#selector(dismissKeyboard))
view.addGestureRecognizer(tap)
@objc func dismissKeyboard (_ sender: UITapGestureRecognizer)
numberField.resignFirstResponder()
【讨论】:
【参考方案21】:Swift 3、iOS 9+
@IBAction private func noteFieldDidEndOnExit(_ sender: UITextField)
UPD:它仍然对我有用。我认为提供此答案的人只是不明白他需要将此操作绑定到情节提要上的 UITextField。
【讨论】:
【参考方案22】:textField.returnKeyType = UIReturnKeyDone;
【讨论】:
以上是关于编辑 UITextField 时如何关闭键盘的主要内容,如果未能解决你的问题,请参考以下文章
UITextField - 检测内置 iPhone 键盘上的输入?